From: "Brian C. Lane" bcl@redhat.com
These patches switch lorax over to use execWith* functions so that we can log everything, and moves the templates for live media creation into their own directory tree.
I have successfully created a f17 boot.iso with lorax (that booted, but failed to run anaconda because of changes on master), and I have created a f17 live iso using the newui iso to drive it (with one small patch to anaconda).
Brian C. Lane (4): livemedia-creator: cleanup logging a bit clean up command execution move live templates into their own subdir of share add logging to lorax
share/config_files/live/x86/boot.msg | 5 -- share/config_files/live/x86/grub.conf | 13 ---- share/config_files/live/x86/isolinux.cfg | 99 ------------------------- share/live/arm.tmpl | 79 ++++++++++++++++++++ share/live/config_files/x86/boot.msg | 5 ++ share/live/config_files/x86/grub.conf | 13 ++++ share/live/config_files/x86/isolinux.cfg | 99 +++++++++++++++++++++++++ share/live/efi.tmpl | 51 +++++++++++++ share/live/ppc.tmpl | 117 ++++++++++++++++++++++++++++++ share/live/s390.tmpl | 33 +++++++++ share/live/sparc.tmpl | 38 ++++++++++ share/live/x86.tmpl | 77 ++++++++++++++++++++ src/pylorax/__init__.py | 7 +- src/pylorax/executils.py | 26 ++++++- src/pylorax/imgutils.py | 49 ++++++------- src/pylorax/ltmpl.py | 18 +++-- src/pylorax/sysutils.py | 4 +- src/pylorax/treebuilder.py | 17 +++-- src/sbin/livemedia-creator | 74 +++++++++---------- src/sbin/lorax | 39 ++++++++++- 20 files changed, 655 insertions(+), 208 deletions(-) delete mode 100644 share/config_files/live/x86/boot.msg delete mode 100644 share/config_files/live/x86/grub.conf delete mode 100644 share/config_files/live/x86/isolinux.cfg create mode 100644 share/live/arm.tmpl create mode 100644 share/live/config_files/x86/boot.msg create mode 100644 share/live/config_files/x86/grub.conf create mode 100644 share/live/config_files/x86/isolinux.cfg create mode 100644 share/live/efi.tmpl create mode 100644 share/live/ppc.tmpl create mode 100644 share/live/s390.tmpl create mode 100644 share/live/sparc.tmpl create mode 100644 share/live/x86.tmpl
From: "Brian C. Lane" bcl@redhat.com
--- src/sbin/livemedia-creator | 61 ++++++++++++++++++++++--------------------- 1 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/src/sbin/livemedia-creator b/src/sbin/livemedia-creator index 3d0c5d2..1dfc75f 100755 --- a/src/sbin/livemedia-creator +++ b/src/sbin/livemedia-creator @@ -179,7 +179,6 @@ class IsoMountpoint(object): raise Exception("Error creating temporary directory")
cmd = ["mount","-o","loop",self.iso_path,self.mount_dir] - log.debug( cmd ) execWithRedirect( cmd[0], cmd[1:] )
self.kernel = self.mount_dir+"/isolinux/vmlinuz" @@ -203,7 +202,6 @@ class IsoMountpoint(object):
def umount( self ): cmd = ["umount", self.mount_dir] - log.debug( cmd ) execWithRedirect( cmd[0], cmd[1:] ) os.rmdir( self.mount_dir )
@@ -212,7 +210,6 @@ class IsoMountpoint(object): Get the iso's label using isoinfo """ cmd = [ "isoinfo", "-d", "-i", self.iso_path ] - log.debug( cmd ) isoinfo_output = execWithCapture( cmd[0], cmd[1:] ) log.debug( isoinfo_output ) for line in isoinfo_output.splitlines(): @@ -295,8 +292,6 @@ class VirtualInstall( object ): cmd.append("--arch") cmd.append(arch)
- log.debug( cmd ) - rc = execWithRedirect( cmd[0], cmd[1:] ) if rc: raise Exception("Problem starting virtual install") @@ -355,8 +350,6 @@ def anaconda_install( disk_img, disk_size, kickstart, repo, args ): "--script", "--repo", repo_url ] cmd += args
- log.debug( cmd ) - return execWithRedirect( cmd[0], cmd[1:] )
@@ -498,8 +491,9 @@ def make_livecd( disk_img, squashfs_args="", templatedir=None, # Link /images to work_dir/images to make the templates happy if os.path.islink( joinpaths( installroot, "images" ) ): os.unlink( joinpaths( installroot, "images" ) ) - subprocess.check_call(["/bin/ln", "-s", joinpaths( work_dir, "images" ), - joinpaths( installroot, "images" )]) + cmd = ["/bin/ln", "-s", joinpaths(work_dir, "images"), + joinpaths(installroot, "images")] + execWithRedirect(cmd[0], cmd[1:])
isolabel = isolabel or "{0.name} {0.version} {1.basearch}".format(product, arch) if len(isolabel) > 32: @@ -524,6 +518,33 @@ def make_livecd( disk_img, squashfs_args="", templatedir=None, return work_dir
+def setup_logging(opts): + # Setup logging to console and to logfile + log.setLevel( logging.DEBUG ) + pylorax_log.setLevel( logging.DEBUG ) + + sh = logging.StreamHandler() + sh.setLevel( logging.INFO ) + fmt = logging.Formatter("%(asctime)s: %(message)s") + sh.setFormatter( fmt ) + log.addHandler( sh ) + pylorax_log.addHandler( sh ) + + fh = logging.FileHandler( filename=opts.logfile, mode="w" ) + fh.setLevel( logging.DEBUG ) + fmt = logging.Formatter("%(asctime)s %(levelname)s %(name)s: %(message)s") + fh.setFormatter( fmt ) + log.addHandler( fh ) + pylorax_log.addHandler( fh ) + + # External program output log + program_log.setLevel(logging.DEBUG) + logfile = os.path.abspath(os.path.dirname(opts.logfile))+"/program.log" + fh = logging.FileHandler( filename=logfile, mode="w") + fh.setLevel( logging.DEBUG ) + program_log.addHandler( fh ) + + if __name__ == '__main__': parser = argparse.ArgumentParser( description="Create Live Install Media", fromfile_prefix_chars="@" ) @@ -618,27 +639,7 @@ if __name__ == '__main__':
opts = parser.parse_args()
- # Setup logging to console and to logfile - log.setLevel( logging.DEBUG ) - pylorax_log.setLevel( logging.DEBUG ) - sh = logging.StreamHandler() - sh.setLevel( logging.INFO ) - fmt = logging.Formatter("%(asctime)s: %(message)s") - sh.setFormatter( fmt ) - log.addHandler( sh ) - pylorax_log.addHandler( sh ) - fh = logging.FileHandler( filename=opts.logfile, mode="w" ) - fh.setLevel( logging.DEBUG ) - fmt = logging.Formatter("%(asctime)s %(levelname)s %(name)s: %(message)s") - fh.setFormatter( fmt ) - log.addHandler( fh ) - pylorax_log.addHandler( fh ) - # External program output log - program_log.setLevel(logging.DEBUG) - logfile = os.path.abspath(os.path.dirname(opts.logfile))+"/program.log" - fh = logging.FileHandler( filename=logfile, mode="w") - fh.setLevel( logging.DEBUG ) - program_log.addHandler( fh ) + setup_logging(opts)
log.debug( opts )
From: "Brian C. Lane" bcl@redhat.com
Switch to using execWith* so that the command and its output can be logged. To capture the output setup a logger named "program"
livemedia-creator captures all of this into program.log --- src/pylorax/__init__.py | 7 +++-- src/pylorax/executils.py | 26 +++++++++++++++++++--- src/pylorax/imgutils.py | 49 ++++++++++++++++++------------------------- src/pylorax/ltmpl.py | 18 +++++++++------- src/pylorax/sysutils.py | 4 ++- src/pylorax/treebuilder.py | 17 ++++++++------- src/sbin/livemedia-creator | 14 ++++-------- 7 files changed, 74 insertions(+), 61 deletions(-)
diff --git a/src/pylorax/__init__.py b/src/pylorax/__init__.py index cf48f0e..5c1d2a9 100644 --- a/src/pylorax/__init__.py +++ b/src/pylorax/__init__.py @@ -30,7 +30,7 @@ import os import ConfigParser import tempfile import locale -import subprocess +from subprocess import CalledProcessError import selinux
from base import BaseLoraxClass, DataHolder @@ -47,6 +47,7 @@ from treebuilder import RuntimeBuilder, TreeBuilder from buildstamp import BuildStamp from treeinfo import TreeInfo from discinfo import DiscInfo +from executils import execWithRedirect
class ArchData(DataHolder): lib64_arches = ("x86_64", "ppc64", "sparc64", "s390x", "ia64") @@ -140,8 +141,8 @@ class Lorax(BaseLoraxClass):
if domacboot: try: - subprocess.check_call(["rpm", "-q", "hfsplus-tools"]) - except subprocess.CalledProcessError: + execWithRedirect("rpm", ["-q", "hfsplus-tools"]) + except CalledProcessError: logger.critical("you need to install hfsplus-tools to create mac images") sys.exit(1)
diff --git a/src/pylorax/executils.py b/src/pylorax/executils.py index f1be30c..2845509 100644 --- a/src/pylorax/executils.py +++ b/src/pylorax/executils.py @@ -70,9 +70,11 @@ class tee(threading.Thread): # @param stdout The file descriptor to redirect stdout to. # @param stderr The file descriptor to redirect stderr to. # @param root The directory to chroot to before running command. +# @param preexec_fn function to pass to Popen +# @param cwd working directory to pass to Popen # @return The return code of command. def execWithRedirect(command, argv, stdin = None, stdout = None, - stderr = None, root = '/'): + stderr = None, root = None, preexec_fn=None, cwd=None): def chroot (): os.chroot(root)
@@ -115,6 +117,13 @@ def execWithRedirect(command, argv, stdin = None, stdout = None, env = os.environ.copy() env.update({"LC_ALL": "C"})
+ if root: + preexec_fn = chroot + cwd = root + program_log.info("chrooting into %s" % (cwd,)) + elif cwd: + program_log.info("chdiring into %s" % (cwd,)) + try: #prepare tee proceses proc_std = tee(pstdout, stdout, program_log.info, command) @@ -127,7 +136,7 @@ def execWithRedirect(command, argv, stdin = None, stdout = None, proc = subprocess.Popen([command] + argv, stdin=stdin, stdout=pstdin, stderr=perrin, - preexec_fn=chroot, cwd=root, + preexec_fn=preexec_fn, cwd=cwd, env=env)
proc.wait() @@ -170,8 +179,10 @@ def execWithRedirect(command, argv, stdin = None, stdout = None, # @param stdin The file descriptor to read stdin from. # @param stderr The file descriptor to redirect stderr to. # @param root The directory to chroot to before running command. +# @param preexec_fn function to pass to Popen +# @param cwd working directory to pass to Popen # @return The output of command from stdout. -def execWithCapture(command, argv, stdin = None, stderr = None, root='/'): +def execWithCapture(command, argv, stdin = None, stderr = None, root=None, preexec_fn=None, cwd=None): def chroot(): os.chroot(root)
@@ -207,11 +218,18 @@ def execWithCapture(command, argv, stdin = None, stderr = None, root='/'): env = os.environ.copy() env.update({"LC_ALL": "C"})
+ if root: + preexec_fn = chroot + cwd = root + program_log.info("chrooting into %s" % (cwd,)) + elif cwd: + program_log.info("chdiring into %s" % (cwd,)) + try: proc = subprocess.Popen([command] + argv, stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - preexec_fn=chroot, cwd=root, + preexec_fn=preexec_fn, cwd=cwd, env=env)
while True: diff --git a/src/pylorax/imgutils.py b/src/pylorax/imgutils.py index 5ec6e8a..8da4b8c 100644 --- a/src/pylorax/imgutils.py +++ b/src/pylorax/imgutils.py @@ -22,12 +22,14 @@ logger = logging.getLogger("pylorax.imgutils")
import os, tempfile from os.path import join, dirname -from pylorax.sysutils import cpfile -from subprocess import * +from subprocess import CalledProcessError import sys import traceback from time import sleep
+from pylorax.sysutils import cpfile +from pylorax.executils import execWithRedirect, execWithCapture + ######## Functions for making container images (cpio, squashfs) ##########
def mkcpio(rootdir, outfile, compression="xz", compressargs=["-9"]): @@ -36,7 +38,6 @@ def mkcpio(rootdir, outfile, compression="xz", compressargs=["-9"]): compressargs will be used on the compression commandline.''' if compression not in (None, "xz", "gzip", "lzma"): raise ValueError, "Unknown compression type %s" % compression - chdir = lambda: os.chdir(rootdir) if compression == "xz": compressargs.insert(0, "--check=crc32") if compression is None: @@ -44,9 +45,9 @@ def mkcpio(rootdir, outfile, compression="xz", compressargs=["-9"]): compressargs = [] logger.debug("mkcpio %s | %s %s > %s", rootdir, compression, " ".join(compressargs), outfile) - find = Popen(["find", ".", "-print0"], stdout=PIPE, preexec_fn=chdir) + find = Popen(["find", ".", "-print0"], stdout=PIPE, cwd=rootdir) cpio = Popen(["cpio", "--null", "--quiet", "-H", "newc", "-o"], - stdin=find.stdout, stdout=PIPE, preexec_fn=chdir) + stdin=find.stdout, stdout=PIPE, cwd=rootdir) comp = Popen([compression] + compressargs, stdin=cpio.stdout, stdout=open(outfile, "wb")) comp.wait() @@ -56,9 +57,7 @@ def mksquashfs(rootdir, outfile, compression="default", compressargs=[]): '''Make a squashfs image containing the given rootdir.''' if compression != "default": compressargs = ["-comp", compression] + compressargs - cmd = ["mksquashfs", rootdir, outfile] + compressargs - logger.debug(" ".join(cmd)) - return call(cmd) + return execWithRedirect("mksquashfs", [rootdir, outfile] + compressargs)
######## Utility functions ###############################################
@@ -70,17 +69,17 @@ def mksparse(outfile, size): def loop_attach(outfile): '''Attach a loop device to the given file. Return the loop device name. Raises CalledProcessError if losetup fails.''' - dev = check_output(["losetup", "--find", "--show", outfile], stderr=PIPE) + dev = execWithCapture("losetup", ["--find", "--show", outfile]) return dev.strip()
def loop_detach(loopdev): '''Detach the given loop device. Return False on failure.''' - return (call(["losetup", "--detach", loopdev]) == 0) + return (execWithRedirect("losetup", ["--detach", loopdev]) == 0)
def get_loop_name(path): '''Return the loop device associated with the path. Raises RuntimeError if more than one loop is associated''' - buf = check_output(["losetup", "-j", path], stderr=PIPE) + buf = execWithCapture("losetup", ["-j", path]) if len(buf.splitlines()) > 1: # there should never be more than one loop device listed raise RuntimeError("multiple loops associated with %s" % path) @@ -93,15 +92,14 @@ def dm_attach(dev, size, name=None): raises CalledProcessError if dmsetup fails.''' if name is None: name = tempfile.mktemp(prefix="lorax.imgutils.", dir="") - check_call(["dmsetup", "create", name, "--table", - "0 %i linear %s 0" % (size/512, dev)], - stdout=PIPE, stderr=PIPE) + execWithRedirect("dmsetup", ["create", name, "--table", + "0 %i linear %s 0" % (size/512, dev)]) return name
def dm_detach(dev): '''Detach the named devicemapper device. Returns False if dmsetup fails.''' dev = dev.replace("/dev/mapper/", "") # strip prefix, if it's there - return call(["dmsetup", "remove", dev], stdout=PIPE, stderr=PIPE) + return execWithRedirect("dmsetup", ["remove", dev])
def mount(dev, opts="", mnt=None): '''Mount the given device at the given mountpoint, using the given opts. @@ -116,8 +114,7 @@ def mount(dev, opts="", mnt=None): if opts: mount += ["-o", opts] mount += [dev, mnt] - logger.debug(" ".join(mount)) - check_call(mount) + execWithRedirect(mount[0], mount[1:]) return mnt
def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0): @@ -127,11 +124,10 @@ def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0): umount = ["umount"] if lazy: umount += ["-l"] umount += [mnt] - logger.debug(" ".join(umount)) count = 0 while maxretry > 0: try: - rv = check_call(umount) + rv = execWithRedirect(umount[0], umount[1:]) except CalledProcessError: count += 1 if count == maxretry: @@ -139,8 +135,7 @@ def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0): logger.warn("failed to unmount %s. retrying (%d/%d)...", mnt, count, maxretry) if logger.getEffectiveLevel() <= logging.DEBUG: - fuser = check_output(["fuser", "-vm", mnt], - stderr=STDOUT) + fuser = execWithCapture("fuser", ["-vm", mnt]) logger.debug("fuser -vm:\n%s\n", fuser) sleep(retrysleep) else: @@ -155,9 +150,9 @@ def copytree(src, dest, preserve=True): links, acls, sparse files, xattrs, selinux contexts, etc. If preserve is False, uses cp -R (useful for modeless filesystems)''' logger.debug("copytree %s %s", src, dest) - chdir = lambda: os.chdir(src) cp = ["cp", "-a"] if preserve else ["cp", "-R", "-L"] - check_call(cp + [".", os.path.abspath(dest)], preexec_fn=chdir) + cp += [".", os.path.abspath(dest)] + execWithRedirect(cp[0], cp[1:], cwd=src)
def do_grafts(grafts, dest, preserve=True): '''Copy each of the items listed in grafts into dest. @@ -256,9 +251,7 @@ class PartitionMount(object): # kpartx -p p -v -a /tmp/diskV2DiCW.im # add map loop2p1 (253:2): 0 3481600 linear /dev/loop2 2048 # add map loop2p2 (253:3): 0 614400 linear /dev/loop2 3483648 - cmd = [ "kpartx", "-v", "-p", "p", "-a", self.disk_img ] - logger.debug(cmd) - kpartx_output = check_output(cmd) + kpartx_output = execWithCapture("kpartx", ["-v", "-p", "p", "-a", self.disk_img]) logger.debug(kpartx_output)
# list of (deviceName, sizeInBytes) @@ -296,7 +289,7 @@ class PartitionMount(object): umount( self.mount_dir ) os.rmdir(self.mount_dir) self.mount_dir = None - call(["kpartx", "-d", self.disk_img]) + execWithRedirect("kpartx", ["-d", self.disk_img])
######## Functions for making filesystem images ########################## @@ -312,7 +305,7 @@ def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=[], mountargs="", gr size = estimate_size(rootdir, graft, fstype) with LoopDev(outfile, size) as loopdev: try: - check_output(["mkfs.%s" % fstype] + mkfsargs + [loopdev]) + execWithRedirect("mkfs.%s" % fstype, mkfsargs + [loopdev]) except CalledProcessError as e: logger.error("mkfs exited with a non-zero return code: %d" % e.returncode) logger.error(e.output) diff --git a/src/pylorax/ltmpl.py b/src/pylorax/ltmpl.py index 0edd5ab..8032213 100644 --- a/src/pylorax/ltmpl.py +++ b/src/pylorax/ltmpl.py @@ -25,11 +25,12 @@ logger = logging.getLogger("pylorax.ltmpl")
import os, re, glob, shlex, fnmatch from os.path import basename, isdir -from subprocess import check_call, check_output, CalledProcessError, STDOUT +from subprocess import CalledProcessError
from sysutils import joinpaths, cpfile, mvfile, replace, remove from yumhelper import * # Lorax*Callback classes from base import DataHolder +from pylorax.executils import execWithRedirect, execWithCapture
from mako.lookup import TemplateLookup from mako.exceptions import text_error_template @@ -368,9 +369,10 @@ class LoraxTemplateRunner(object): ''' if outfile is None: outfile = self._out("etc/gconf/gconf.xml.defaults") - check_call(["gconftool-2", "--direct", + cmd = ["gconftool-2", "--direct", "--config-source=xml:readwrite:%s" % outfile, - "--set", "--type", keytype, path, value]) + "--set", "--type", keytype, path, value] + execWithRedirect(cmd[0], cmd[1:])
def log(self, msg): ''' @@ -404,16 +406,15 @@ class LoraxTemplateRunner(object): remove ${f} %endfor ''' - chdir = lambda: None + cwd = None cmd = cmdlist logger.debug('running command: %s', cmd) if cmd[0].startswith("--chdir="): - dirname = cmd[0].split('=',1)[1] - chdir = lambda: os.chdir(dirname) + cwd = cmd[0].split('=',1)[1] cmd = cmd[1:]
try: - output = check_output(cmd, preexec_fn=chdir, stderr=STDOUT) + output = execWithCapture(cmd[0], cmd[1:], cwd=cwd) if output: logger.debug('command output:\n%s', output) logger.debug("command finished successfully") @@ -550,6 +551,7 @@ class LoraxTemplateRunner(object): '--quiet', cmd) # XXX for some reason 'systemctl enable/disable' always returns 1 try: - check_call(systemctl + units) + cmd = systemctl + units + execWithRedirect(cmd[0], cmd[1:]) except CalledProcessError: pass diff --git a/src/pylorax/sysutils.py b/src/pylorax/sysutils.py index d35906c..52f849a 100644 --- a/src/pylorax/sysutils.py +++ b/src/pylorax/sysutils.py @@ -32,6 +32,7 @@ import glob import shutil import subprocess
+from pylorax.executils import execWithRedirect
def joinpaths(*args, **kwargs): path = os.path.sep.join(args) @@ -105,4 +106,5 @@ def remove(target): os.unlink(target)
def linktree(src, dst): - subprocess.check_call(["/bin/cp", "-al", src, dst]) + execWithRedirect("/bin/cp", ["-al", src, dst]) + diff --git a/src/pylorax/treebuilder.py b/src/pylorax/treebuilder.py index 3061f15..460d742 100644 --- a/src/pylorax/treebuilder.py +++ b/src/pylorax/treebuilder.py @@ -22,13 +22,13 @@ logger = logging.getLogger("pylorax.treebuilder")
import os, re from os.path import basename, isdir -from subprocess import check_call, check_output
from sysutils import joinpaths, remove from shutil import copytree, copy2 from base import DataHolder from ltmpl import LoraxTemplateRunner import imgutils +from pylorax.executils import execWithRedirect, execWithCapture
templatemap = { 'i386': 'x86.tmpl', @@ -45,7 +45,8 @@ templatemap = {
def generate_module_info(moddir, outfile=None): def module_desc(mod): - return check_output(["modinfo", "-F", "description", mod]).strip() + output = execWithCapture("modinfo", ["-F", "description", mod]) + return output.strip() def read_module_set(name): return set(l.strip() for l in open(joinpaths(moddir,name)) if ".ko" in l) modsets = {'scsi':read_module_set("modules.block"), @@ -148,7 +149,7 @@ class RuntimeBuilder(object): for kver in os.listdir(moddir): ksyms = joinpaths(root, "boot/System.map-%s" % kver) logger.info("doing depmod and module-info for %s", kver) - check_call(["depmod", "-a", "-F", ksyms, "-b", root, kver]) + execWithRedirect("depmod", ["-a", "-F", ksyms, "-b", root, kver]) generate_module_info(moddir+kver, outfile=moddir+"module-info")
def create_runtime(self, outfile="/tmp/squashfs.img", compression="xz", compressargs=[], size=1): @@ -165,8 +166,8 @@ class RuntimeBuilder(object): # Reset selinux context on new rootfs with imgutils.LoopDev( joinpaths(workdir, "LiveOS/rootfs.img") ) as loopdev: with imgutils.Mount(loopdev) as mnt: - cmd = ["chroot", mnt, "setfiles", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/selinux", "/etc/selinux/targeted/contexts/files/file_contexts", "/"] - check_call(cmd) + cmd = [ "setfiles", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/selinux", "/etc/selinux/targeted/contexts/files/file_contexts", "/"] + execWithRedirect(cmd[0], cmd[1:], root=mnt)
# squash the live rootfs and clean up workdir imgutils.mksquashfs(workdir, outfile, compression, compressargs) @@ -206,8 +207,8 @@ class TreeBuilder(object): if backup: initrd = joinpaths(self.vars.inroot, kernel.initrd.path) os.rename(initrd, initrd + backup) - check_call(["chroot", self.vars.inroot] + \ - dracut + [kernel.initrd.path, kernel.version]) + cmd = dracut + [kernel.initrd.path, kernel.version] + execWithRedirect(cmd[0], cmd[1:], root=self.vars.inroot) os.unlink(joinpaths(self.vars.inroot,"/proc/modules"))
def build(self): @@ -220,7 +221,7 @@ class TreeBuilder(object): for section, data in self.treeinfo_data.items(): if 'boot.iso' in data: iso = joinpaths(self.vars.outroot, data['boot.iso']) - check_call(["implantisomd5", iso]) + execWithRedirect("implantisomd5", [iso])
@property def dracut_hooks_path(self): diff --git a/src/sbin/livemedia-creator b/src/sbin/livemedia-creator index 1dfc75f..6717ed3 100755 --- a/src/sbin/livemedia-creator +++ b/src/sbin/livemedia-creator @@ -178,8 +178,7 @@ class IsoMountpoint(object): if not self.mount_dir: raise Exception("Error creating temporary directory")
- cmd = ["mount","-o","loop",self.iso_path,self.mount_dir] - execWithRedirect( cmd[0], cmd[1:] ) + execWithRedirect("mount", ["-o", "loop", self.iso_path, self.mount_dir])
self.kernel = self.mount_dir+"/isolinux/vmlinuz" self.initrd = self.mount_dir+"/isolinux/initrd.img" @@ -201,16 +200,14 @@ class IsoMountpoint(object): self.get_iso_label()
def umount( self ): - cmd = ["umount", self.mount_dir] - execWithRedirect( cmd[0], cmd[1:] ) + execWithRedirect("umount", [self.mount_dir]) os.rmdir( self.mount_dir )
def get_iso_label( self ): """ Get the iso's label using isoinfo """ - cmd = [ "isoinfo", "-d", "-i", self.iso_path ] - isoinfo_output = execWithCapture( cmd[0], cmd[1:] ) + isoinfo_output = execWithCapture("isoinfo", ["-d", "-i", self.iso_path]) log.debug( isoinfo_output ) for line in isoinfo_output.splitlines(): if line.startswith("Volume id: "): @@ -491,9 +488,8 @@ def make_livecd( disk_img, squashfs_args="", templatedir=None, # Link /images to work_dir/images to make the templates happy if os.path.islink( joinpaths( installroot, "images" ) ): os.unlink( joinpaths( installroot, "images" ) ) - cmd = ["/bin/ln", "-s", joinpaths(work_dir, "images"), - joinpaths(installroot, "images")] - execWithRedirect(cmd[0], cmd[1:]) + execWithRedirect("/bin/ln", ["-s", joinpaths(work_dir, "images"), + joinpaths(installroot, "images")])
isolabel = isolabel or "{0.name} {0.version} {1.basearch}".format(product, arch) if len(isolabel) > 32:
From: "Brian C. Lane" bcl@redhat.com
live media isn't exactly the same as the Anaconda install media. Right now this amounts to needing a root= cmdline argument but in the future there may be other differences.
This also reverts 543755784679 on the new copies of the templates. --- share/config_files/live/x86/boot.msg | 5 -- share/config_files/live/x86/grub.conf | 13 ---- share/config_files/live/x86/isolinux.cfg | 99 ------------------------- share/live/arm.tmpl | 79 ++++++++++++++++++++ share/live/config_files/x86/boot.msg | 5 ++ share/live/config_files/x86/grub.conf | 13 ++++ share/live/config_files/x86/isolinux.cfg | 99 +++++++++++++++++++++++++ share/live/efi.tmpl | 51 +++++++++++++ share/live/ppc.tmpl | 117 ++++++++++++++++++++++++++++++ share/live/s390.tmpl | 33 +++++++++ share/live/sparc.tmpl | 38 ++++++++++ share/live/x86.tmpl | 77 ++++++++++++++++++++ src/sbin/livemedia-creator | 5 +- 13 files changed, 515 insertions(+), 119 deletions(-) delete mode 100644 share/config_files/live/x86/boot.msg delete mode 100644 share/config_files/live/x86/grub.conf delete mode 100644 share/config_files/live/x86/isolinux.cfg create mode 100644 share/live/arm.tmpl create mode 100644 share/live/config_files/x86/boot.msg create mode 100644 share/live/config_files/x86/grub.conf create mode 100644 share/live/config_files/x86/isolinux.cfg create mode 100644 share/live/efi.tmpl create mode 100644 share/live/ppc.tmpl create mode 100644 share/live/s390.tmpl create mode 100644 share/live/sparc.tmpl create mode 100644 share/live/x86.tmpl
diff --git a/share/config_files/live/x86/boot.msg b/share/config_files/live/x86/boot.msg deleted file mode 100644 index ff54899..0000000 --- a/share/config_files/live/x86/boot.msg +++ /dev/null @@ -1,5 +0,0 @@ - -splash.lss - - - Press the 01<ENTER>07 key to begin the installation process. - diff --git a/share/config_files/live/x86/grub.conf b/share/config_files/live/x86/grub.conf deleted file mode 100644 index 3547540..0000000 --- a/share/config_files/live/x86/grub.conf +++ /dev/null @@ -1,13 +0,0 @@ -#debug --graphics -default=0 -splashimage=@SPLASHPATH@ -timeout 5 -hiddenmenu -title @PRODUCT@ @VERSION@ - findiso - kernel @KERNELPATH@ @ROOT@ liveimg rd.luks=0 rd.md=0 rd.dm=0 - initrd @INITRDPATH@ -title Test this media & start @PRODUCT@ - findiso - kernel @KERNELPATH@ @ROOT@ quiet liveimg rd.live.check rd.luks=0 rd.md=0 rd.dm=0 - initrd @INITRDPATH@ diff --git a/share/config_files/live/x86/isolinux.cfg b/share/config_files/live/x86/isolinux.cfg deleted file mode 100644 index e158834..0000000 --- a/share/config_files/live/x86/isolinux.cfg +++ /dev/null @@ -1,99 +0,0 @@ -default vesamenu.c32 -timeout 600 - -menu autoboot Starting @PRODUCT@ in # second{,s}. Press any key to interrupt. - -# Clear the screen when exiting the menu, instead of leaving the menu displayed. -# For vesamenu, this means the graphical background is still displayed without -# the menu itself for as long as the screen remains in graphics mode. -menu clear -menu background splash.png -menu title @PRODUCT@ @VERSION@ -menu vshift 8 -menu rows 18 -menu margin 8 -#menu hidden -menu helpmsgrow 15 -menu tabmsgrow 13 - -# Border Area -menu color border * #00000000 #00000000 none - -# Selected item -menu color sel 0 #ffffffff #00000000 none - -# Title bar -menu color title 0 #ff7ba3d0 #00000000 none - -# Press [Tab] message -menu color tabmsg 0 #ff3a6496 #00000000 none - -# Unselected menu item -menu color unsel 0 #84b8ffff #00000000 none - -# Selected hotkey -menu color hotsel 0 #84b8ffff #00000000 none - -# Unselected hotkey -menu color hotkey 0 #ffffffff #00000000 none - -# Help text -menu color help 0 #ffffffff #00000000 none - -# A scrollbar of some type? Not sure. -menu color scrollbar 0 #ffffffff #ff355594 none - -# Timeout msg -menu color timeout 0 #ffffffff #00000000 none -menu color timeout_msg 0 #ffffffff #00000000 none - -# Command prompt text -menu color cmdmark 0 #84b8ffff #00000000 none -menu color cmdline 0 #ffffffff #00000000 none - -# Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message. - -menu tabmsg Press Tab for full configuration options on menu items. -menu separator # insert an empty line -menu separator # insert an empty line -label linux - menu label ^Start @PRODUCT@ (default) - menu default - kernel vmlinuz - append initrd=initrd.img @ROOT@ quiet liveimg rd.luks=0 rd.md=0 rd.dm=0 -label check - menu label Test this ^media & start @PRODUCT@ - kernel vmlinuz - append initrd=initrd.img @ROOT@ quiet liveimg rd.live.check rd.luks=0 rd.md=0 rd.dm=0 -menu separator # insert an empty line -# utilities submenu -menu begin ^Troubleshooting - menu title Troubleshooting -label vesa - menu indent count 5 - menu label Start @PRODUCT@ in ^basic graphics mode - text help - Try this option out if you're having trouble installing - @PRODUCT@. - endtext - kernel vmlinuz - append initrd=initrd.img @ROOT@ xdriver=vesa nomodeset quiet liveimg rd.luks=0 rd.md=0 rd.dm=0 -label memtest - menu label Run a ^memory test - text help - If your system is having issues, a problem with your - system's memory may be the cause. Use this utility to - see if the memory is working correctly. - endtext - kernel memtest -menu separator # insert an empty line -label local - menu label Boot from ^local drive - localboot 0xffff -menu separator # insert an empty line -menu separator # insert an empty line -label returntomain - menu label Return to ^main menu - menu exit -menu end - diff --git a/share/live/arm.tmpl b/share/live/arm.tmpl new file mode 100644 index 0000000..bf6eef9 --- /dev/null +++ b/share/live/arm.tmpl @@ -0,0 +1,79 @@ +<%page args="kernels, runtime_img, runtime_base, basearch, outroot, arch"/> +<% +configdir="tmp/config_files/uboot" +PXEBOOTDIR="images/pxeboot" +BOOTDIR="boot" +KERNELDIR=PXEBOOTDIR +LIVEDIR="LiveOS" + +# different platforms use different kernel load addresses. +# include a 'baseline' kernel for no 'flavor'. +kernelAddress = { 'baseline' : '0x00008000', + 'highbank' : '0x00008000', + 'imx' : '0x90008000', + 'kirkwood' : '0x00008000', + 'mvebu' : '0x00008000', + 'omap' : '0x80008000', + 'tegra' : '0x00008000', + } +%> + +mkdir ${LIVEDIR} +install ${runtime_img} ${LIVEDIR}/squashfs.img +treeinfo stage2 mainimage ${LIVEDIR}/squashfs.img + +## install kernels +mkdir ${KERNELDIR} +%for kernel in kernels: + %if kernel.flavor: + installkernel images-${kernel.flavor}-${basearch} ${kernel.path} ${KERNELDIR}/vmlinuz-${kernel.flavor} + installinitrd images-${kernel.flavor}-${basearch} ${kernel.initrd.path} ${KERNELDIR}/initrd-${kernel.flavor}.img + + # create U-Boot wrapped images + + runcmd mkimage \ + -A arm -O linux -T ramdisk -C none \ + -a 0 -e 0 \ + -n "${product.name} ${product.version} ${kernel.flavor} ${kernel.arch}" \ + -d ${outroot}/${KERNELDIR}/initrd-${kernel.flavor}.img \ + ${outroot}/${KERNELDIR}/uInitrd-${kernel.flavor} + + runcmd mkimage \ + -A arm -O linux -T kernel -C none \ + -a ${kernelAddress[kernel.flavor]} -e ${kernelAddress[kernel.flavor]} \ + -n "${product.name} ${product.version} ${kernel.flavor} ${kernel.arch}" \ + -d ${outroot}/${KERNELDIR}/vmlinuz-${kernel.flavor} \ + ${outroot}/${KERNELDIR}/uImage-${kernel.flavor} + + treeinfo images-${kernel.flavor}-${basearch} uimage ${KERNELDIR}/uImage-${kernel.flavor} + treeinfo images-${kernel.flavor}-${basearch} uinitrd ${KERNELDIR}/uInitrd-${kernel.flavor} + + %else: + installkernel images-${basearch} ${kernel.path} ${KERNELDIR}/vmlinuz + installinitrd images-${basearch} ${kernel.initrd.path} ${KERNELDIR}/initrd.img + + # create U-Boot wrapped images + + runcmd mkimage \ + -A arm -O linux -T ramdisk -C none \ + -a 0 -e 0 \ + -n "${product.name} ${product.version} ${kernel.arch}" \ + -d ${outroot}/${KERNELDIR}/initrd.img \ + ${outroot}/${KERNELDIR}/uInitrd + + runcmd mkimage \ + -A arm -O linux -T kernel -C none \ + -a ${kernelAddress['baseline']} -e ${kernelAddress['baseline']} \ + -n "${product.name} ${product.version} ${kernel.arch}" \ + -d ${outroot}/${KERNELDIR}/vmlinuz \ + ${outroot}/${KERNELDIR}/uImage + + treeinfo images-${basearch} uimage ${KERNELDIR}/uImage + treeinfo images-${basearch} uinitrd ${KERNELDIR}/uInitrd + + %endif +%endfor + + +## FIXME: ARM may need some extra boot config + diff --git a/share/live/config_files/x86/boot.msg b/share/live/config_files/x86/boot.msg new file mode 100644 index 0000000..ff54899 --- /dev/null +++ b/share/live/config_files/x86/boot.msg @@ -0,0 +1,5 @@ + +splash.lss + + - Press the 01<ENTER>07 key to begin the installation process. + diff --git a/share/live/config_files/x86/grub.conf b/share/live/config_files/x86/grub.conf new file mode 100644 index 0000000..3547540 --- /dev/null +++ b/share/live/config_files/x86/grub.conf @@ -0,0 +1,13 @@ +#debug --graphics +default=0 +splashimage=@SPLASHPATH@ +timeout 5 +hiddenmenu +title @PRODUCT@ @VERSION@ + findiso + kernel @KERNELPATH@ @ROOT@ liveimg rd.luks=0 rd.md=0 rd.dm=0 + initrd @INITRDPATH@ +title Test this media & start @PRODUCT@ + findiso + kernel @KERNELPATH@ @ROOT@ quiet liveimg rd.live.check rd.luks=0 rd.md=0 rd.dm=0 + initrd @INITRDPATH@ diff --git a/share/live/config_files/x86/isolinux.cfg b/share/live/config_files/x86/isolinux.cfg new file mode 100644 index 0000000..e158834 --- /dev/null +++ b/share/live/config_files/x86/isolinux.cfg @@ -0,0 +1,99 @@ +default vesamenu.c32 +timeout 600 + +menu autoboot Starting @PRODUCT@ in # second{,s}. Press any key to interrupt. + +# Clear the screen when exiting the menu, instead of leaving the menu displayed. +# For vesamenu, this means the graphical background is still displayed without +# the menu itself for as long as the screen remains in graphics mode. +menu clear +menu background splash.png +menu title @PRODUCT@ @VERSION@ +menu vshift 8 +menu rows 18 +menu margin 8 +#menu hidden +menu helpmsgrow 15 +menu tabmsgrow 13 + +# Border Area +menu color border * #00000000 #00000000 none + +# Selected item +menu color sel 0 #ffffffff #00000000 none + +# Title bar +menu color title 0 #ff7ba3d0 #00000000 none + +# Press [Tab] message +menu color tabmsg 0 #ff3a6496 #00000000 none + +# Unselected menu item +menu color unsel 0 #84b8ffff #00000000 none + +# Selected hotkey +menu color hotsel 0 #84b8ffff #00000000 none + +# Unselected hotkey +menu color hotkey 0 #ffffffff #00000000 none + +# Help text +menu color help 0 #ffffffff #00000000 none + +# A scrollbar of some type? Not sure. +menu color scrollbar 0 #ffffffff #ff355594 none + +# Timeout msg +menu color timeout 0 #ffffffff #00000000 none +menu color timeout_msg 0 #ffffffff #00000000 none + +# Command prompt text +menu color cmdmark 0 #84b8ffff #00000000 none +menu color cmdline 0 #ffffffff #00000000 none + +# Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message. + +menu tabmsg Press Tab for full configuration options on menu items. +menu separator # insert an empty line +menu separator # insert an empty line +label linux + menu label ^Start @PRODUCT@ (default) + menu default + kernel vmlinuz + append initrd=initrd.img @ROOT@ quiet liveimg rd.luks=0 rd.md=0 rd.dm=0 +label check + menu label Test this ^media & start @PRODUCT@ + kernel vmlinuz + append initrd=initrd.img @ROOT@ quiet liveimg rd.live.check rd.luks=0 rd.md=0 rd.dm=0 +menu separator # insert an empty line +# utilities submenu +menu begin ^Troubleshooting + menu title Troubleshooting +label vesa + menu indent count 5 + menu label Start @PRODUCT@ in ^basic graphics mode + text help + Try this option out if you're having trouble installing + @PRODUCT@. + endtext + kernel vmlinuz + append initrd=initrd.img @ROOT@ xdriver=vesa nomodeset quiet liveimg rd.luks=0 rd.md=0 rd.dm=0 +label memtest + menu label Run a ^memory test + text help + If your system is having issues, a problem with your + system's memory may be the cause. Use this utility to + see if the memory is working correctly. + endtext + kernel memtest +menu separator # insert an empty line +label local + menu label Boot from ^local drive + localboot 0xffff +menu separator # insert an empty line +menu separator # insert an empty line +label returntomain + menu label Return to ^main menu + menu exit +menu end + diff --git a/share/live/efi.tmpl b/share/live/efi.tmpl new file mode 100644 index 0000000..644f009 --- /dev/null +++ b/share/live/efi.tmpl @@ -0,0 +1,51 @@ +<%page args="configdir, KERNELDIR, efiarch"/> +<% +EFIBOOTDIR="EFI/BOOT" +APPLE_EFI_ICON=inroot+"/usr/share/pixmaps/bootloader/fedora.icns" +APPLE_EFI_DISKNAME=inroot+"/usr/share/pixmaps/bootloader/fedora-media.vol" +%> + +mkdir ${EFIBOOTDIR} +install boot/efi/EFI/redhat/grub.efi ${EFIBOOTDIR}/BOOT${efiarch}.efi +install boot/grub/splash.xpm.gz ${EFIBOOTDIR} + +## actually make the EFI images +${make_efiboot("images/efiboot.img")} +%if domacboot: + ${make_efiboot("images/macboot.img", imgtype="apple")} +%endif + +## This is kinda gross, but then... so's EFI. +<%def name="make_efiboot(img, include_kernel=False, disk=False, imgtype='default')"> + <% + kdir = EFIBOOTDIR if include_kernel else KERNELDIR + eficonf = "%s/BOOT%s.conf" % (EFIBOOTDIR, efiarch) + args = "--label=ANACONDA" + if disk: args += " --disk" + if imgtype == "apple": args += ' --apple --icon=%s --diskname=%s --product="%s %s"' % (APPLE_EFI_ICON, APPLE_EFI_DISKNAME, product.name, product.version) + %> + %if include_kernel: + copy ${KERNELDIR}/vmlinuz ${EFIBOOTDIR} + copy ${KERNELDIR}/initrd.img ${EFIBOOTDIR} + %endif + install ${configdir}/grub.conf ${eficonf} + replace @PRODUCT@ '${product.name}' ${eficonf} + replace @VERSION@ ${product.version} ${eficonf} + replace @KERNELPATH@ /${kdir}/vmlinuz ${eficonf} + replace @INITRDPATH@ /${kdir}/initrd.img ${eficonf} + replace @SPLASHPATH@ /EFI/BOOT/splash.xpm.gz ${eficonf} + %if disk: + ## FIXME: using root= causes problems with product.img (see bug 811979) + replace @ROOT@ root=live:LABEL=ANACONDA ${eficonf} + %else: + replace @ROOT@ 'root=live:CDLABEL=${isolabel|udev}' ${eficonf} + %endif + %if efiarch == 'IA32': + copy ${eficonf} ${EFIBOOTDIR}/BOOT.conf + %endif + runcmd mkefiboot ${args} ${outroot}/${EFIBOOTDIR} ${outroot}/${img} + %if include_kernel: + remove ${EFIBOOTDIR}/vmlinuz + remove ${EFIBOOTDIR}/initrd.img + %endif +</%def> diff --git a/share/live/ppc.tmpl b/share/live/ppc.tmpl new file mode 100644 index 0000000..3ff15da --- /dev/null +++ b/share/live/ppc.tmpl @@ -0,0 +1,117 @@ +<%page args="kernels, runtime_img, basearch, libdir, inroot, outroot, product, isolabel"/> +<% +configdir="tmp/config_files/ppc" +BOOTDIR="ppc" +LIVEDIR="LiveOS" +MACDIR=BOOTDIR+"/mac" +NETBOOTDIR="images/netboot" + +WRAPPER="usr/sbin/wrapper" +WRAPPER_DATA="usr/"+libdir+"/kernel-wrapper" + +bitsizes = set() +prepboot = "" + +## NOTE: yaboot freaks out and stops parsing its config if it sees a '', +## so we can't use the udev escape sequences in the root arg. +## Instead we'll just replace any non-ASCII characters in the isolabel +## with '_', which means we won't need any udev escapes. +isolabel = ''.join(ch if ch.isalnum() else '_' for ch in isolabel) + +rootarg = "root=live:CDLABEL=%s" % isolabel +%> + +mkdir ${LIVEDIR} +install ${runtime_img} ${LIVEDIR}/squashfs.img +treeinfo stage2 mainimage ${LIVEDIR}/squashfs.img + +## install bootloaders. +## NOTE: there's two different bootloader setups here: +## ppc/chrp: for normal PPC systems. needs 'addnote' run on yaboot. +## uses /etc/yaboot.conf, as is the default. +## ppc/mac: for PowerMacs. no 'addnote' (it breaks some Macs!) +## ofboot.b picks one of /ppc/ppc{32,64}/yaboot.conf for yaboot, +## thus automatically booting the correct kernel for the machine. +mkdir ${BOOTDIR} +## boot stuff for normal (CHRP/PREP) PPC systems +install ${configdir}/bootinfo.txt ${BOOTDIR} +install boot/efika.forth ${BOOTDIR} +mkdir ${BOOTDIR}/chrp +install usr/lib/yaboot/yaboot ${BOOTDIR}/chrp +runcmd ${inroot}/usr/lib/yaboot/addnote ${outroot}/${BOOTDIR}/chrp/yaboot +## special boot dir for PowerMacs +mkdir ${MACDIR} +install usr/lib/yaboot/yaboot ${MACDIR} +install ${configdir}/ofboot.b ${MACDIR} + +## copy mapping and magic files needed for isos +install ${configdir}/mapping ${BOOTDIR} +install ${configdir}/magic ${BOOTDIR} + +## NOTE: PPC is kind of funky. There's three possible "arch" setups here: +## ppc, ppc64, and 'hybrid' (ppc userspace, both ppc & ppc64 kernels). + +## Install kernel and bootloader config (in separate places for each arch) +%for kernel in kernels: + <% + bits = 64 if kernel.arch == "ppc64" else 32 + ## separate dirs/images for each arch + KERNELDIR=BOOTDIR+"/ppc%s" % bits + NETIMG=NETBOOTDIR+"/ppc%s.img" % bits + bitsizes.add(bits) + %> + ## install kernel + mkdir ${KERNELDIR} ${NETBOOTDIR} + installkernel images-${kernel.arch} ${kernel.path} ${KERNELDIR}/vmlinuz + installinitrd images-${kernel.arch} ${kernel.initrd.path} ${KERNELDIR}/initrd.img + + ## install arch-specific bootloader config + install ${configdir}/yaboot.conf.in ${KERNELDIR}/yaboot.conf + replace @BITS@ ${bits} ${KERNELDIR}/yaboot.conf + replace @PRODUCT@ '${product.name}' ${KERNELDIR}/yaboot.conf + replace @VERSION@ ${product.version} ${KERNELDIR}/yaboot.conf + replace @ROOT@ "${rootarg}" ${KERNELDIR}/yaboot.conf + + ## kernel-wrapper magic that makes the netboot combined ppc{32,64}.img + runcmd ${inroot}/${WRAPPER} -p of \ + -D ${inroot}/${WRAPPER_DATA} \ + -i ${outroot}/${KERNELDIR}/initrd.img \ + ${outroot}/${KERNELDIR}/vmlinuz \ + -o ${outroot}/${NETIMG} + treeinfo images-${kernel.arch} zimage ${NETIMG} + ## PReP is 32-bit only + %if bits == 32: + ## Yes, this is supposed to be a relative path + <% prepboot="-prep-boot " + NETIMG %> + %endif +%endfor + +## choose correct yaboot.conf +mkdir etc +%if len(bitsizes) == 2: + ## both kernels means hybrid - use the magic hybrid config + install ${configdir}/yaboot.conf.3264 etc/yaboot.conf + replace @PRODUCT@ ${product.name} etc/yaboot.conf + replace @VERSION@ ${product.version} etc/yaboot.conf + replace @ROOT@ "${rootarg}" etc/yaboot.conf +%else: + ## single arch - use the arch-specific yaboot.conf from above + copy ${KERNELDIR}/yaboot.conf etc/yaboot.conf +%endif + +## make boot.iso +runcmd mkisofs -o ${outroot}/images/boot.iso -chrp-boot -U \ + ${prepboot} -part -hfs -T -r -l -J \ + -A "${product.name} ${product.version}" -sysid PPC -V '${isolabel}' \ + -volset "${product.version}" -volset-size 1 -volset-seqno 1 \ + -hfs-volid ${product.version} -hfs-bless ${outroot}/${MACDIR} \ + -map ${inroot}/${configdir}/mapping \ + -no-desktop -allow-multidot -graft-points \ + etc=${outroot}/etc \ + ${BOOTDIR}=${outroot}/${BOOTDIR} \ + ${NETBOOTDIR}=${outroot}/${NETBOOTDIR} \ + ${LIVEDIR}=${outroot}/${LIVEDIR} + +%for kernel in kernels: + treeinfo images-${kernel.arch} boot.iso images/boot.iso +%endfor diff --git a/share/live/s390.tmpl b/share/live/s390.tmpl new file mode 100644 index 0000000..f02963d --- /dev/null +++ b/share/live/s390.tmpl @@ -0,0 +1,33 @@ +<%page args="kernels, runtime_img, runtime_base, basearch, outroot"/> +<% +configdir="tmp/config_files/s390" +BOOTDIR="images" +KERNELDIR=BOOTDIR +INITRD_ADDRESS="0x02000000" +# The assumption seems to be that there is only one s390 kernel, ever +kernel = kernels[0] +%> + +mkdir images +install ${runtime_img} images +treeinfo stage2 mainimage images/${runtime_base} + +## install bootloader (such as it is) and bootloader config +install ${configdir}/redhat.exec ${BOOTDIR} +install ${configdir}/generic.prm ${BOOTDIR} +install ${configdir}/generic.ins . + +## configure bootloader +replace @INITRD_LOAD_ADDRESS@ ${INITRD_ADDRESS} generic.ins + +## install kernel +installkernel images-${basearch} ${kernel.path} ${KERNELDIR}/kernel.img +installinitrd images-${basearch} ${kernel.initrd.path} ${KERNELDIR}/initrd.img + +## s390 needs some extra boot config +createaddrsize ${INITRD_ADDRESS} ${outroot}/${BOOTDIR}/initrd.img ${outroot}/${BOOTDIR}/initrd.addrsize + +## s390 also has some special treeinfo data +treeinfo images-${basearch} initrd.addrsize ${BOOTDIR}/initrd.addrsize +treeinfo images-${basearch} generic.prm ${BOOTDIR}/generic.prm +treeinfo images-${basearch} generic.ins generic.ins diff --git a/share/live/sparc.tmpl b/share/live/sparc.tmpl new file mode 100644 index 0000000..2452f80 --- /dev/null +++ b/share/live/sparc.tmpl @@ -0,0 +1,38 @@ +<%page args="kernels, runtime_img, basearch, outroot, product, isolabel"/> +<% +configdir="tmp/config_files/sparc" +BOOTDIR="boot" +LIVEDIR="LiveOS" +%> + +mkdir ${LIVEDIR} +install ${runtime_img} ${LIVEDIR}/squashfs.img +treeinfo stage2 mainimage ${LIVEDIR}/squashfs.img + +## install bootloader and config files +install boot/*.b ${BOOTDIR} +install ${configdir}/silo.conf ${BOOTDIR} +install ${configdir}/boot.msg ${BOOTDIR} + +## configure bootloader +replace @VERSION@ ${product.version} ${BOOTDIR}/boot.msg +replace @PRODUCT@ '${product.name}' ${BOOTDIR}/boot.msg +replace @ROOT@ 'root=live:CDLABEL=${isolabel|udev}' ${BOOTDIR}/silo.conf + +## install kernels +## FIXME: this will overwrite if there are multiple sparc kernels +%for kernel in kernels: + installkernel images-${basearch} ${kernel.path} ${BOOTDIR}/vmlinuz + installinitrd images-${basearch} ${kernel.initrd.path} ${BOOTDIR}/initrd.img +%endfor + +## make boot.iso +runcmd mkisofs -R -J -T -G /${BOOTDIR}/isofs.b -B ... \ + -s /${BOOTDIR}/silo.conf -r -V '${isolabel}' \ + -A "${product.name} ${product.version}" \ + -x Fedora -x repodata \ + -sparc-label "${product.name} ${product.version} Boot Disc" \ + -o ${outroot}/images/boot.iso \ + -graft-points ${BOOTDIR}=${outroot}/${BOOTDIR} \ + ${LIVEDIR}=${outroot}/${LIVEDIR} +treeinfo images-${basearch} boot.iso images/boot.iso diff --git a/share/live/x86.tmpl b/share/live/x86.tmpl new file mode 100644 index 0000000..023c1af --- /dev/null +++ b/share/live/x86.tmpl @@ -0,0 +1,77 @@ +<%page args="kernels, runtime_img, basearch, outroot, product, isolabel"/> +<% +configdir="tmp/config_files/x86" +SYSLINUXDIR="usr/share/syslinux" +PXEBOOTDIR="images/pxeboot" +BOOTDIR="isolinux" +KERNELDIR=PXEBOOTDIR +LIVEDIR="LiveOS" +%> + +mkdir ${LIVEDIR} +install ${runtime_img} ${LIVEDIR}/squashfs.img +treeinfo stage2 mainimage ${LIVEDIR}/squashfs.img + +## install bootloader and config files +mkdir ${BOOTDIR} +install ${SYSLINUXDIR}/isolinux.bin ${BOOTDIR} +install ${SYSLINUXDIR}/vesamenu.c32 ${BOOTDIR} +install ${configdir}/isolinux.cfg ${BOOTDIR} +install ${configdir}/boot.msg ${BOOTDIR} +install ${configdir}/grub.conf ${BOOTDIR} +install usr/share/anaconda/boot/syslinux-splash.png ${BOOTDIR}/splash.png +install boot/memtest* ${BOOTDIR}/memtest + +## configure bootloader +replace @VERSION@ ${product.version} ${BOOTDIR}/grub.conf ${BOOTDIR}/isolinux.cfg ${BOOTDIR}/*.msg +replace @PRODUCT@ '${product.name}' ${BOOTDIR}/grub.conf ${BOOTDIR}/isolinux.cfg ${BOOTDIR}/*.msg +replace @ROOT@ 'root=live:CDLABEL=${isolabel|udev}' ${BOOTDIR}/isolinux.cfg + +## install kernels +mkdir ${KERNELDIR} +%for kernel in kernels: + %if kernel.flavor: + installkernel images-xen ${kernel.path} ${KERNELDIR}/vmlinuz-${kernel.flavor} + installinitrd images-xen ${kernel.initrd.path} ${KERNELDIR}/initrd-${kernel.flavor}.img + %else: + installkernel images-${basearch} ${kernel.path} ${KERNELDIR}/vmlinuz + installinitrd images-${basearch} ${kernel.initrd.path} ${KERNELDIR}/initrd.img + %endif +%endfor + +hardlink ${KERNELDIR}/vmlinuz ${BOOTDIR} +hardlink ${KERNELDIR}/initrd.img ${BOOTDIR} +%if basearch == 'x86_64': + treeinfo images-xen kernel ${KERNELDIR}/vmlinuz + treeinfo images-xen initrd ${KERNELDIR}/initrd.img +%endif + +## WHeeeeeeee, EFI. +## We could remove the basearch restriction someday.. +<% efiargs=""; efigraft=""; efihybrid="" %> +%if exists("boot/efi/EFI/redhat/grub.efi") and basearch != 'i386': + <% + efiarch = 'X64' if basearch=='x86_64' else 'IA32' + efigraft="EFI/BOOT={0}/EFI/BOOT".format(outroot) + images = ["images/efiboot.img"] + if domacboot: + images.append("images/macboot.img") + for img in images: + efiargs += " -eltorito-alt-boot -e {0} -no-emul-boot".format(img) + efigraft += " {0}={1}/{0}".format(img,outroot) + efihybrid = "--uefi --mac" if domacboot else "--uefi" + %> + <%include file="efi.tmpl" args="configdir=configdir, KERNELDIR=KERNELDIR, efiarch=efiarch"/> +%endif + +## make boot.iso +runcmd mkisofs -o ${outroot}/images/boot.iso \ + -b ${BOOTDIR}/isolinux.bin -c ${BOOTDIR}/boot.cat \ + -boot-load-size 4 -boot-info-table -no-emul-boot \ + ${efiargs} -R -J -V '${isolabel}' -T -graft-points \ + ${BOOTDIR}=${outroot}/${BOOTDIR} \ + ${KERNELDIR}=${outroot}/${KERNELDIR} \ + ${LIVEDIR}=${outroot}/${LIVEDIR} \ + ${efigraft} +runcmd isohybrid ${efihybrid} ${outroot}/images/boot.iso +treeinfo images-${basearch} boot.iso images/boot.iso diff --git a/src/sbin/livemedia-creator b/src/sbin/livemedia-creator index 6717ed3..af16f3b 100755 --- a/src/sbin/livemedia-creator +++ b/src/sbin/livemedia-creator @@ -466,7 +466,7 @@ def make_livecd( disk_img, squashfs_args="", templatedir=None,
# TreeBuilder expects the config files to be in /tmp/config_files # I think these should be release specific, not from lorax, but for now - configdir = joinpaths(templatedir,"config_files/live/") + configdir = joinpaths(templatedir,"live/config_files/") configdir_path = "tmp/config_files" fullpath = joinpaths(installroot, configdir_path) if os.path.exists(fullpath): @@ -498,7 +498,8 @@ def make_livecd( disk_img, squashfs_args="", templatedir=None,
tb = TreeBuilder( product=product, arch=arch, inroot=installroot, outroot=work_dir, - runtime=runtime, isolabel=isolabel, templatedir=templatedir) + runtime=runtime, isolabel=isolabel, + templatedir=joinpaths(templatedir,"live/")) log.info( "Rebuilding initrds" ) if not opts.dracut_args: dracut_args = DRACUT_DEFAULT
From: "Brian C. Lane" bcl@redhat.com
--- src/sbin/lorax | 39 ++++++++++++++++++++++++++++++++++++++- 1 files changed, 38 insertions(+), 1 deletions(-)
diff --git a/src/sbin/lorax b/src/sbin/lorax index b4acd01..c1f709a 100755 --- a/src/sbin/lorax +++ b/src/sbin/lorax @@ -20,9 +20,14 @@ # # Red Hat Author(s): Martin Gracik mgracik@redhat.com # - from __future__ import print_function
+import logging +log = logging.getLogger("lorax") +program_log = logging.getLogger("program") +pylorax_log = logging.getLogger("pylorax") + + import sys import os import tempfile @@ -32,6 +37,32 @@ import ConfigParser import yum import pylorax
+def setup_logging(opts): + # Setup logging to console and to logfile + log.setLevel( logging.DEBUG ) + pylorax_log.setLevel( logging.DEBUG ) + + sh = logging.StreamHandler() + sh.setLevel( logging.INFO ) + fmt = logging.Formatter("%(asctime)s: %(message)s") + sh.setFormatter( fmt ) + log.addHandler( sh ) + pylorax_log.addHandler( sh ) + + fh = logging.FileHandler( filename=opts.logfile, mode="w" ) + fh.setLevel( logging.DEBUG ) + fmt = logging.Formatter("%(asctime)s %(levelname)s %(name)s: %(message)s") + fh.setFormatter( fmt ) + log.addHandler( fh ) + pylorax_log.addHandler( fh ) + + # External program output log + program_log.setLevel(logging.DEBUG) + logfile = os.path.abspath(os.path.dirname(opts.logfile))+"/program.log" + fh = logging.FileHandler( filename=logfile, mode="w") + fh.setLevel( logging.DEBUG ) + program_log.addHandler( fh ) +
def main(args): version = "{0} 0.1".format(os.path.basename(args[0])) @@ -76,6 +107,8 @@ def main(args): help="volume id", metavar="STRING") optional.add_option("--nomacboot", help="", action="store_false", default=True, dest="domacboot") + optional.add_option("--logfile", default="./lorax.log", + help="Path to logfile" )
# add the option groups to the parser parser.add_option_group(required) @@ -105,6 +138,10 @@ def main(args): if os.path.exists(outputdir): parser.error("output directory should not exist.")
+ opts.logfile = os.path.abspath(opts.logfile) + + setup_logging(opts) + # create the temporary directory for lorax tempdir = tempfile.mkdtemp(prefix="lorax.", dir=tempfile.gettempdir())
Everything looks good, except the inconsistent parentheses around the function arguments.
----- Original Message -----
From: "Brian C. Lane" bcl@redhat.com
These patches switch lorax over to use execWith* functions so that we can log everything, and moves the templates for live media creation into their own directory tree.
I have successfully created a f17 boot.iso with lorax (that booted, but failed to run anaconda because of changes on master), and I have created a f17 live iso using the newui iso to drive it (with one small patch to anaconda).
Brian C. Lane (4): livemedia-creator: cleanup logging a bit clean up command execution move live templates into their own subdir of share add logging to lorax
share/config_files/live/x86/boot.msg | 5 -- share/config_files/live/x86/grub.conf | 13 ---- share/config_files/live/x86/isolinux.cfg | 99
share/live/arm.tmpl | 79 ++++++++++++++++++++ share/live/config_files/x86/boot.msg | 5 ++ share/live/config_files/x86/grub.conf | 13 ++++ share/live/config_files/x86/isolinux.cfg | 99 +++++++++++++++++++++++++ share/live/efi.tmpl | 51 +++++++++++++ share/live/ppc.tmpl | 117 ++++++++++++++++++++++++++++++ share/live/s390.tmpl | 33 +++++++++ share/live/sparc.tmpl | 38 ++++++++++ share/live/x86.tmpl | 77 ++++++++++++++++++++ src/pylorax/__init__.py | 7 +- src/pylorax/executils.py | 26 ++++++- src/pylorax/imgutils.py | 49 ++++++------- src/pylorax/ltmpl.py | 18 +++-- src/pylorax/sysutils.py | 4 +- src/pylorax/treebuilder.py | 17 +++-- src/sbin/livemedia-creator | 74 +++++++++---------- src/sbin/lorax | 39 ++++++++++- 20 files changed, 655 insertions(+), 208 deletions(-) delete mode 100644 share/config_files/live/x86/boot.msg delete mode 100644 share/config_files/live/x86/grub.conf delete mode 100644 share/config_files/live/x86/isolinux.cfg create mode 100644 share/live/arm.tmpl create mode 100644 share/live/config_files/x86/boot.msg create mode 100644 share/live/config_files/x86/grub.conf create mode 100644 share/live/config_files/x86/isolinux.cfg create mode 100644 share/live/efi.tmpl create mode 100644 share/live/ppc.tmpl create mode 100644 share/live/s390.tmpl create mode 100644 share/live/sparc.tmpl create mode 100644 share/live/x86.tmpl
-- 1.7.7.6
anaconda-patches mailing list anaconda-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
On Mon, Jul 30, 2012 at 07:14:20AM -0400, Martin Gracik wrote:
Everything looks good, except the inconsistent parentheses around the function arguments.
If you mean the extra spaces I added to the lmc code, I agree, I'm going to go through and clean all those up one of those days. I still don't know why I threw all those in there.
Yeah, I meant those. So if you keep in mind to clean it up, you can push it. :)
----- Original Message -----
On Mon, Jul 30, 2012 at 07:14:20AM -0400, Martin Gracik wrote:
Everything looks good, except the inconsistent parentheses around the function arguments.
If you mean the extra spaces I added to the lmc code, I agree, I'm going to go through and clean all those up one of those days. I still don't know why I threw all those in there.
-- Brian C. Lane | Anaconda Team | IRC: bcl #anaconda | Port Orchard, WA (PST8PDT)
anaconda-patches mailing list anaconda-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
anaconda-patches@lists.fedorahosted.org