diff --git a/rewrite/scratch/buildinstall b/rewrite/scratch/buildinstall
deleted file mode 100755
index a4885f05..00000000
--- a/rewrite/scratch/buildinstall
+++ /dev/null
@@ -1,3 +0,0 @@
-# FIXME: need to update mk-images to take the yumconf
-echo "Making images..."
-$MK_IMAGES $DEBUGSTR $NOGRSTR --imgdir $TREEDIR/install --arch $BUILDARCH --product "$PRODUCTSTR" --version $VERSION --bugurl "$BUGURL" --output $OUTPUT $yumconf
diff --git a/rewrite/scratch/buildinstall.functions b/rewrite/scratch/buildinstall.functions
deleted file mode 100755
index e0910c71..00000000
--- a/rewrite/scratch/buildinstall.functions
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/bin/bash
-
-# pulled right out of mkinitrd....
-DSO_DEPS=""
-LDSO=""
-get_dso_deps() {
- root="$1" ; shift
- bin="$1" ; shift
- DSO_DEPS=""
-
- declare -a FILES
- declare -a NAMES
-
- # this is a hack, but the only better way requires binutils or elfutils
- # be installed. i.e., we need readelf to find the interpretter.
- if [ -z "$LDSO" ]; then
- for ldso in $root/$LIBDIR/ld*.so* ; do
- [ -L $ldso ] && continue
- [ -x $ldso ] || continue
- $ldso --verify $bin >/dev/null 2>&1 || continue
- LDSO=$(echo $ldso |sed -e "s,$root,,")
- done
- fi
-
- # I still hate shell.
- declare -i n=0
- while read NAME I0 FILE ADDR I1 ; do
- [ "$FILE" == "not" ] && FILE="$FILE $ADDR"
- NAMES[$n]="$NAME"
- FILES[$n]="$FILE"
- let n++
- done << EOF
- $(/usr/sbin/chroot $root env LD_TRACE_PRELINKING=1 LD_WARN= \
- LD_TRACE_LOADED_OBJECTS=1 $LDSO $bin)
-EOF
-
- [ ${#FILES[*]} -eq 0 ] && return 1
-
- # we don't want the name of the binary in the list
- if [ "${FILES[0]}" == "$bin" ]; then
- FILES[0]=""
- NAMES[0]=""
- [ ${#FILES[*]} -eq 1 ] && return 1
- fi
-
- declare -i n=0
- while [ $n -lt ${#FILES[*]} ]; do
- FILE="${FILES[$n]}"
- if [ "$FILE" == "not found" ]; then
- cat 1>&2 <.
-#
-
-perl -e 'while (<>) { if (/\\\n/) { chop; s/\\$//; print;} else { print $_; } }' | grep ':.*ko' | sed -e '
-s/\.ko//g
-s,/[^: ]*/,,g
-s/[ ][ ]*/ /g'
-
diff --git a/rewrite/scratch/geninitrdsz.c b/rewrite/scratch/geninitrdsz.c
deleted file mode 100644
index 6dfd9761..00000000
--- a/rewrite/scratch/geninitrdsz.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * geninitrdsz.c
- * Generate initrd.size file for zSeries platforms.
- * Takes an integer argument and writes out the binary representation of
- * that value to the initrd.size file.
- * https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=197773
- *
- * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
- *
- * 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 .
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-int main(int argc,char **argv) {
- unsigned int zero = 0;
- int fd;
- unsigned int size;
- mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
-
- if (argc != 3) {
- printf("Usage: %s [integer size] [output file]\n", basename(argv[0]));
- printf("Example: %s 12288475 initrd.size\n", basename(argv[0]));
- return 0;
- }
-
- size = htonl(atoi(argv[1]));
- fd = open(argv[2], O_CREAT | O_RDWR, mode);
-
- if (write(fd, &zero, sizeof(int)) == -1) {
- perror("writing initrd.size (zero)");
- return errno;
- }
-
- if (write(fd, &size, sizeof(int)) == -1) {
- perror("writing initrd.size (size)");
- return errno;
- }
-
- close(fd);
- return 0;
-}
diff --git a/rewrite/scratch/genmodinfo b/rewrite/scratch/genmodinfo
deleted file mode 100755
index 44c8247d..00000000
--- a/rewrite/scratch/genmodinfo
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/python
-#
-# genmodinfo
-#
-# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
-#
-# 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 .
-#
-
-import commands
-import os
-import string
-import sys
-
-uname = os.uname()[2]
-
-if len(sys.argv) > 1:
- path = sys.argv[1]
-else:
- path = '/lib/modules/%s' % (uname,)
-
-mods = {}
-for root, dirs, files in os.walk(path):
- for file in files:
- mods[file] = os.path.join(root,file)
-
-modules = { 'scsi_hostadapter' : [ 'block' ], 'eth' : [ 'networking'] }
-blacklist = ("floppy", "scsi_mod", "libiscsi")
-
-list = {}
-
-for modtype in modules.keys():
- list[modtype] = {}
- for file in modules[modtype]:
- try:
- f = open('%s/modules.%s' % (path,file),'r')
- except:
- continue
- lines = f.readlines()
- f.close()
- for line in lines:
- line = line.strip()
- if mods.has_key(line):
- desc = commands.getoutput("modinfo -F description %s" % (mods[line])).split("\n")[0]
- desc = desc.strip()
- modname = line[:-3]
- if modname in blacklist:
- continue
- if desc and len(desc) > 65:
- desc = desc[:65]
- if not desc:
- desc = "%s driver" % (modname,)
- modinfo = """
-%s
- %s
- "%s"
-""" % (modname, modtype, desc)
- list[modtype][modname] = modinfo
-
-print "Version 0"
-for type in list.keys():
- modlist = list[type].keys()
- modlist.sort()
- for m in modlist:
- print list[type][m]
diff --git a/rewrite/scratch/mk-images b/rewrite/scratch/mk-images
index 0e72b364..76464378 100755
--- a/rewrite/scratch/mk-images
+++ b/rewrite/scratch/mk-images
@@ -18,154 +18,6 @@
# along with this program. If not, see .
#
-LANG=C
-
-PATH=$PATH:/sbin:/usr/sbin
-IMAGEUUID=$(date +%Y%m%d%H%M).$(uname -i)
-TMPDIR=${TMPDIR:-/tmp}
-
-usage () {
- echo "usage: mk-images []"
- exit 0
-}
-
-DEBUG=""
-BUILDARCH=`uname -m`
-BOOTISO="boot.iso"
-
-while [ $# -gt 0 ]; do
- case $1 in
- --debug)
- DEBUG="--debug"
- shift
- ;;
-
- --noiso)
- BOOTISO=""
- shift
- ;;
-
- --arch)
- BUILDARCH=$2
- shift; shift
- ;;
-
- --imgdir)
- IMGPATH=$2
- shift; shift
- ;;
-
- --product)
- PRODUCT=$2
- shift; shift
- ;;
-
- --version)
- VERSION=$2
- shift; shift
- ;;
-
- --bugurl)
- BUGURL=$2
- shift; shift
- ;;
-
- --output)
- TOPDESTPATH=$2
- shift; shift
- ;;
-
- --nogr)
- echo "*** DeprecationWarning: ignoring --nogr option." >&2
- shift
- ;;
-
- --mindir)
- echo "*** DeprecationWarning: ignoring --mindir option." >&2
- shift; shift
- ;;
-
- --stg2dir)
- echo "*** DeprecationWarning: please use --imgdir instead of --stg2dir." >&2
- shift; shift
- ;;
-
- *)
- yumconf=$1
- shift
- ;;
- esac
-done
-
-if [ -z "$TOPDESTPATH" -o -z "$IMGPATH" -o -z "$PRODUCT" -o -z "$VERSION" ]; then usage; fi
-
-TOPDIR=$(echo $0 | sed "s,/[^/]*$,,")
-if [ $TOPDIR = $0 ]; then
- $TOPDIR="."
-fi
-TOPDIR=$(cd $TOPDIR; pwd)
-
-# modules that are needed. this is the generic "needed for every arch" stuff
-COMMONMODS="fat vfat nfs sunrpc lockd floppy cramfs loop edd pcspkr squashfs ipv6 virtio_pci"
-USBMODS="ohci-hcd uhci-hcd ehci-hcd hid mousedev usb-storage sd_mod sr_mod ub appletouch"
-FIREWIREMODS="ohci1394 sbp2 fw-ohci fw-sbp2 firewire-sbp2 firewire-ohci"
-IDEMODS="ide-cd ide-cd_mod"
-SCSIMODS="sr_mod sg st sd_mod scsi_mod iscsi_tcp"
-FSMODS="fat msdos vfat ext2 ext3 ext4dev reiserfs jfs xfs gfs2 lock_nolock cifs"
-LVMMODS="dm-mod dm-zero dm-snapshot dm-mirror dm-multipath dm-round-robin dm-emc dm-crypt"
-RAIDMODS="raid0 raid1 raid5 raid6 raid456 raid10 linear"
-CRYPTOMODS="sha256_generic cbc xts lrw aes_generic crypto_blkcipher crc32c ecb arc4"
-PCMCIASOCKMODS="yenta_socket i82365 tcic pcmcia"
-DRMMODS="drm i810 i830 i915 mga nouveau r128 radeon savage sis tdfx via"
-INITRDMODS="$USBMODS $FIREWIREMODS $IDEMODS $SCSIMODS $FSMODS $LVMMODS $RAIDMODS $CRYPTOMODS $COMMONMODS $PCMCIASOCKMODS $DRMMODS =scsi =net"
-
-. $(dirname $0)/buildinstall.functions
-
-# Set, verify, and create paths
- IMAGEPATH=$TOPDESTPATH/images
- FULLMODPATH=$TMPDIR/instimagemods.$$
- FINALFULLMODPATH=$IMGPATH/modules
- INSTIMGPATH=$TOPDESTPATH/images
- KERNELBASE=$TMPDIR/updboot.kernel.$$
-
- KERNELNAME=vmlinuz
- if [ "$BUILDARCH" = "ia64" ]; then
- KERNELDIR="/boot/efi/EFI/redhat"
- else
- KERNELDIR="/boot"
- fi
-
- if [ "$BUILDARCH" = "sparc64" ]; then
- BASEARCH=sparc
- else
- BASEARCH=$BUILDARCH
- fi
-
- # explicit block size setting for some arches (FIXME: we compose
- # ppc64-ish trees as ppc, so we have to set the "wrong" block size)
- if [ "$BUILDARCH" = "sparc64" ]; then
- CRAMBS="--blocksize 8192"
- elif [ "$BUILDARCH" = "sparc" ]; then
- CRAMBS="--blocksize 4096"
- else
- CRAMBS=""
- fi
-
- if [ $BUILDARCH = x86_64 -o $BUILDARCH = s390x ]; then
- LIBDIR=lib64
- else
- LIBDIR=lib
- fi
-
- rm -rf $IMAGEPATH
- rm -rf $FULLMODPATH
- rm -rf $FINALFULLMODPATH
- rm -rf $KERNELBASE
- mkdir -p $IMAGEPATH
- mkdir -p $FULLMODPATH
- mkdir -p $FINALFULLMODPATH
- mkdir -p $KERNELBASE
- mkdir -p $INSTIMGPATH
# Stuff that we need
TRIMPCIIDS=$IMGPATH/usr/lib/anaconda-runtime/trimpciids
diff --git a/rewrite/scratch/scrubtree b/rewrite/scratch/scrubtree
deleted file mode 100755
index 4b87c0d6..00000000
--- a/rewrite/scratch/scrubtree
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/bash
-
-DEBUG=""
-
-if [ "$1" == "--debug" ]; then
- DEBUG="--debug"
- shift
-fi
-
-if [ -z "$1" ]; then
- echo "Usage: $0 /path/to/tree"
- exit 1
-fi
-
-p=$1
-
-STRIP=strip
-ARCH=`uname -m | sed -e 's/i.86/i386/'`
-
-if [ $ARCH = ia64 ]; then
- STRIP="strip --strip-debug"
-fi
-
-if [ $ARCH = x86_64 -o $ARCH = s390x ]; then
- LIBDIR=lib64
-else
- LIBDIR=lib
-fi
-
-# Must create ld.so.conf, because ldconfig does not cache
-# dirs specified on the command line.
-touch $p/etc/ld.so.conf
-mkdir $p/proc
-mount -t proc proc $p/proc
-[ -d $p/usr/X11R6/$LIBDIR ] && echo /usr/X11R6/$LIBDIR > $p/etc/ld.so.conf
-echo /usr/kerberos/$LIBDIR > $p/etc/ld.so.conf
-(cd $p; /usr/sbin/chroot $p usr/sbin/ldconfig )
-
-if [ $ARCH != s390 -a $ARCH != s390x ]; then
- rm -f $p/usr/sbin/ldconfig
-fi
-rm $p/etc/ld.so.conf
-
-#
-# make sure we have links for programs supplied by busybox
-#
-# HOWEVER dont clobber existing programs supplied by other packages if exist
-#
-mv $p/usr/sbin/busybox.anaconda $p/usr/bin/busybox
-(cd $p/usr/bin;
-set $(./busybox 2>&1| awk '/^\t([[:alnum:]_\[]+,)+/' | sed 's/,//g' | sed 's/ +//');
-while [ -n "$1" ]; do
- if [ $1 != "busybox" -a $1 != "sh" -a $1 != "shutdown" -a $1 != "poweroff" -a $1 != "reboot" ]; then
- # if file doesnt already exist, link to busybox
- if [ ! -f "$1" ]; then
- ln -sf ./busybox $1
- else
- [ -n "$DEBUG" ] && echo "Overriding busybox version of $1"
- fi
- fi
- shift
-done
-)
-
-umount $p/proc
-
-for l in `find $p -type f -perm +100 | grep -v "usr/X11R6/$LIBDIR/modules" | xargs file | sed -n 's/^\([^:]*\):.*ELF.*$/\1/p'`; do
- $STRIP $l -R .comment -R .note `objdump -h $l | \
- sed -n 's/^.*\(\.gnu\.warning\.[^ ]*\) .*$/-R \1/p'`
-done
diff --git a/rewrite/scratch/trimpciids b/rewrite/scratch/trimpciids
deleted file mode 100755
index ba946297..00000000
--- a/rewrite/scratch/trimpciids
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/python
-#
-# trimpciids
-#
-# Copyright (C) 2007 Red Hat, Inc. All rights reserved.
-#
-# 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 .
-#
-
-import sys
-import os
-import string
-
-vendors = []
-devices = []
-
-f = open(sys.argv[1])
-if f:
- pcitable = f.readlines()
- f.close()
- for line in pcitable:
- if not line.startswith("alias pci:"):
- continue
- vend = "0x%s" % (line[15:19],)
- dev = "0x%s" % (line[24:28],)
- vend = vend.upper()
- dev = dev.upper()
- if vend not in vendors:
- vendors.append(vend)
- if (vend, dev) not in devices:
- devices.append( (vend, dev) )
-
-for file in sys.argv[2:]:
- if not os.path.exists(file):
- sys.stderr.write("WARNING: non-existent file %s for trimpciids\n" %(file,))
- continue
- f = open(file)
- if f:
- pcitable = f.readlines()
- f.close()
- for line in pcitable:
- if not line.startswith("alias pcivideo:"):
- continue
- vend = "0x%s" % (line[20:24],)
- dev = "0x%s" % (line[29:33],)
- vend = vend.upper()
- dev = dev.upper()
- if vend not in vendors:
- vendors.append(vend)
- if (vend, dev) not in devices:
- devices.append( (vend, dev) )
-
-pciids = sys.stdin.readlines()
-current_vend = 0
-for line in pciids:
- if line.startswith("#") or line == "\n":
- continue
- if line.startswith("\t\t"):
- continue
- if not line.startswith("\t"):
- current_vend = "0x%s" % line.split()[0]
- current_vend = current_vend.upper()
- if current_vend in vendors:
- print line,
- continue
- dev = "0x%s" % line.split()[0]
- dev = dev.upper()
- if (current_vend, dev) in devices:
- print line,
diff --git a/rewrite/scratch/upd-instroot b/rewrite/scratch/upd-instroot
deleted file mode 100755
index 459df289..00000000
--- a/rewrite/scratch/upd-instroot
+++ /dev/null
@@ -1,102 +0,0 @@
-. $(dirname $0)/buildinstall.functions
-
-
-# ..........this is the pylorax.instroot.installPackages() function in lorax
-expandPackageSet() {
- if [ -n "$UPDATES" ]; then
- (cd $UPDATES; find) | (cd $UPDATES ; /bin/cpio --quiet -pmdu $YUMDIR)
- fi
-}
-
-
-
-
-
-
-chown -R root:root $DEST
-chmod -R a+rX-w $DEST
-
-
-
-sed -i 's|\(installforallkernels\) = 0|\1 = 1|' $DEST/etc/yum/pluginconf.d/fedorakmod.conf
-
-#
-# Manual pages in rescue: We dont have man pages in the image, so we point everything (The pages
-# and the man scripts to the /mnt/sysimage. We want the man command to depend only on the
-# man.conf file, so we don't use the $MANPATH env variable. The executables stay unchanged as
-# they will be soft links to /mnt/sysimage.
-#
-echo "Fixing up /etc/man.config to point into /mnt/sysimage"
-#
-# Lets avoid the lines with MANPATH_MAP for now
-#
-sed -i "s,^MANPATH[^_MAP][ \t]*,&/mnt/sysimage," $DEST/etc/man.config
-
-#
-# Lets change the lines with MANPATH_MAP. Don't know how much of a difference this will make.
-#
-sed -i "s,^MANPATH_MAP[ \t]*[a-zA-Z0-9/]*[ \t]*,&/mnt/sysimage," $DEST/etc/man.config
-
-mv $DEST/usr/sbin/anaconda $DEST/usr/bin/anaconda
-mv $DEST/usr/lib/anaconda-runtime/lib* $DEST/usr/$LIBDIR 2>/dev/null
-
-mv $DEST/etc/yum.repos.d $DEST/etc/anaconda.repos.d
-
-find $DEST -type d | xargs chmod 755
-
-if [ -f $DEST/bin/bash ]; then
- rm -f $DEST/bin/ash
- ln -s bash $DEST/bin/sh
-else
- ln -sf busybox $DEST/bin/sh
-fi
-
-[ -d $DEST/bin ] || die "ERROR: directory missing: $DEST/bin"
-[ -d $DEST/sbin ] || die "ERROR: directory missing: $DEST/sbin"
-(cd $DEST/bin; find) | (cd $DEST/bin; /bin/cpio --quiet -pdmu $DEST/usr/bin)
-(cd $DEST/sbin; find) | (cd $DEST/sbin; /bin/cpio --quiet -pdmu $DEST/usr/sbin)
-rm -rf $DEST/bin
-rm -rf $DEST/sbin
-
-# Fix relative links like /usr/bin/udevinfo -> ../../sbin/udevadm
-for brokenlink in $(find $DEST/usr/{bin,sbin} -follow -lname '*') ; do
- target="$(readlink $brokenlink)"
- for pathbit in bin sbin; do
- # if it starts with "../../sbin/", remove that
- newtarget="${target##../../$pathbit/}"
- # if we removed something, replace it with the proper path
- if [ "$newtarget" != "$target" ]; then
- # make it ../sbin/ instead
- ln -sf "../$pathbit/$newtarget" "$brokenlink"
- fi
- done
-done
-
-find $DEST -name "*.a" | grep -v kernel-wrapper/wrapper.a | xargs rm -rf
-find $DEST -name "lib*.la" |grep -v "usr/$LIBDIR/gtk-2.0" | xargs rm -rf
-
-# nuke some python stuff we don't need
-for d in idle distutils bsddb lib-old hotshot doctest.py pydoc.py site-packages/japanese site-packages/japanese.pth ; do
- rm -rf $DEST/$d
-done
-
-$DEST/usr/lib/anaconda-runtime/scrubtree $DEST
-
-echo "Creating debug dir"
-mkdir -p $DEST/usr/lib/debug
-mkdir -p $DEST/usr/src/debug
-
-find $DEST -name "*.py" | while read fn; do
- rm -f ${fn}o
- rm -f ${fn}c
- ln -sf /dev/null ${fn}c
-done
-
-# some python stuff we don't need for install image
-rm -rf $DEST/usr/$LIBDIR/python?.?/site-packages/distutils/
-rm -rf $DEST/usr/$LIBDIR/python?.?/site-packages/lib-dynload/japanese
-rm -rf $DEST/usr/$LIBDIR/python?.?/site-packages/encodings/
-rm -rf $DEST/usr/$LIBDIR/python?.?/site-packages/compiler/
-rm -rf $DEST/usr/$LIBDIR/python?.?/site-packages/email/test/
-rm -rf $DEST/usr/$LIBDIR/python?.?/site-packages/curses/
-rm -rf $DEST/usr/$LIBDIR/python?.?/site-packages/pydoc.py
diff --git a/rewrite/to_remove_from_anaconda b/rewrite/to_remove_from_anaconda
index 9ed2a31d..c9ffdaf6 100644
--- a/rewrite/to_remove_from_anaconda
+++ b/rewrite/to_remove_from_anaconda
@@ -1,4 +1,4 @@
- scripts/buildinstall
+DONE scripts/buildinstall
scripts/buildinstall.functions
DONE scripts/makestamp.py
DONE scripts/maketreeinfo.py
@@ -9,12 +9,12 @@ DONE scripts/maketreeinfo.py
scripts/mk-images.ppc
scripts/mk-images.s390
scripts/mk-images.x86
- scripts/scrubtree
- scripts/upd-instroot
+DONE scripts/scrubtree
+DONE scripts/upd-instroot
- utils/trimpciids
+DONE utils/trimpciids
utils/mk-s390-cdboot.c
- utils/filtermoddeps
- utils/geninitrdsz.c
- utils/genmodinfo
+DONE utils/filtermoddeps
+DONE utils/geninitrdsz.c
+DONE utils/genmodinfo
utils/modlist
diff --git a/src/bin/lorax b/src/bin/lorax
index bfdcf887..8465ac1e 100755
--- a/src/bin/lorax
+++ b/src/bin/lorax
@@ -1,9 +1,9 @@
-#!/usr/bin/python -tt
+#!/usr/bin/env python
#
# lorax
# Install image and tree support data generation tool.
#
-# Copyright (C) 2008 Red Hat, Inc.
+# Copyright (C) 2008, 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
@@ -19,113 +19,80 @@
# along with this program. If not, see .
#
# Author(s): David Cantrell
+# Martin Gracik
#
-import getopt
-import os
import sys
+import os
+from optparse import OptionParser, OptionGroup
-from pylorax import Lorax
+import pylorax
-def usage(prog):
- print("Usage: %s -v VERSION -p PRODUCT -r RELEASE -o PATH REPO\n" % (prog,))
- print("Required arguments:")
- print(" -v, --version=STRING Version identifier.")
- print(" -p, --product=STRING Product name.")
- print(" -r, --release=STRING Release information or comment.\n")
- print(" -o, --output=PATHSPEC Where to write output files.")
- print("Optional arguments:")
- print(" -d, --debug Enable debugging messages.")
- print(" -t, --variant=STRING Variant name.")
- print(" -b, --bugurl=URL Bug reporting URL for the product.")
- print(" -u, --updates=PATHSPEC Path to find updated RPMS.")
- print(" -m, --mirrorlist=REPO Mirror list repo, may be listed multiple times.")
- print(" -c, --confdir=PATHSPEC Path to config files (default: /etc/lorax).")
- print(" -C, --cleanup Cleanup on exit.\n")
- print("A 'REPO' specification is a valid yum repository path.\n")
- print("See the man page lorax(8) for more information.")
-if __name__ == "__main__":
- prog = os.path.basename(sys.argv[0])
- opts, args, mirrorlist, extrarepos = [], [], [], []
- confdir, version, product, release, output, repo = None, None, None, None, None, None
- debug = False
- cleanup = False
- variant, updates = '', ''
- bugurl = 'your distribution provided bug reporting tool.'
+if __name__ == '__main__':
+ version = '%s 0.1' % (os.path.basename(sys.argv[0]),)
+ usage = '%prog -p PRODUCT -v VERSION -r RELEASE -o OUTPUT REPOSITORY'
- try:
- opts, args = getopt.getopt(sys.argv[1:], "v:p:r:o:dt:b:u:m:c:CV",
- ["version=", "product=", "release=",
- "output=", "debug", "variant=",
- "bugurl=", "updates=", "mirrorlist=",
- "confdir=", "cleanup"])
- except getopt.GetoptError:
- usage(prog)
- sys.exit(1)
+ parser = OptionParser(usage=usage)
- for o, a in opts:
- if o in ('-v', '--version'):
- version = a
- elif o in ('-p', '--product'):
- product = a
- elif o in ('-r', '--release'):
- release = a
- elif o in ('-o', '--output'):
- output = a
- elif o in ('-d', '--debug'):
- debug = True
- elif o in ('-t', '--variant'):
- variant = a
- elif o in ('-b', '--bugurl'):
- bugurl = a
- elif o in ('-u', '--updates'):
- updates = a
- elif o in ('-m', '--mirrorlist'):
- mirrorlist.append(a)
- elif o in ('-c', '--confdir'):
- if os.path.isdir(a):
- confdir = a
- else:
- sys.stderr.write("ERROR: %s is not a directory.\n" % (a,))
- elif o in ('-C', '--cleanup'):
- cleanup = True
- elif o in ('-V'):
- # XXX: need to fix this
- #pylorax.show_version(prog)
- sys.exit(0)
+ def check_dir(option, opt_str, value, parser):
+ if os.path.isdir(value):
+ setattr(parser.values, option.dest, value)
+ else:
+ parser.error('%s is not a directory' % (value,))
- if version is None or product is None or release is None or output is None:
- sys.stderr.write("ERROR: Missing a required argument.\n")
- sys.exit(1)
+ # XXX "options" should not be required
+ # required
+ group = OptionGroup(parser, 'Required')
+ group.add_option('-p', '--product', help='Product name.',
+ metavar='STRING')
+ group.add_option('-v', '--version', help='Version identifier.',
+ metavar='STRING')
+ group.add_option('-r', '--release', help='Release information or comment.',
+ metavar='STRING')
+ group.add_option('-o', '--output', help='Destination directory.',
+ metavar='PATHSPEC')
+ parser.add_option_group(group)
- if len(args) == 0:
- sys.stderr.write("ERROR: Missing repo to use for image generation.\n")
- sys.exit(1)
+ # XXX are all of these used?
+ # optional
+ group = OptionGroup(parser, 'Optional')
+ group.add_option('-d', '--debug', help='Enable debugging messages.',
+ action='store_true', default=False)
+ group.add_option('-t', '--variant', help='Variant name.',
+ metavar='STRING')
+ group.add_option('-b', '--bugurl', help='Bug reporting URL for the product.',
+ metavar='URL', default='your distribution provided bug reporting tool.')
+ group.add_option('-u', '--updates', help='Path to find updated RPMS.',
+ metavar='PATHSPEC')
+ group.add_option('-m', '--mirrorlist', help='Mirror list repository, may be listed multiple times.',
+ metavar='REPOSITORY', action='append', default=[])
+ group.add_option('-c', '--confdir', help='Path to config files (default: /etc/lorax).',
+ metavar='PATHSPEC', action='callback', callback=check_dir,
+ type='string', default='/etc/lorax')
+ group.add_option('-C', '--cleanup', help='Cleanup on exit.',
+ action='store_true', default=False)
+ group.add_option('-V', help='Print version and exit.',
+ action='store_true', default=False, dest='printver')
+ parser.add_option_group(group)
- lorax = Lorax(repos=args, output=output, mirrorlist=mirrorlist)
+ # additional information
+ group = OptionGroup(parser, 'Additional information',
+ 'A "REPOSITORY" specification is a valid yum repository path.\n'
+ 'See the man page lorax(8) for more information.')
+ parser.add_option_group(group)
- if confdir is not None:
- lorax.conf['confdir'] = confdir
+ (opts, args) = parser.parse_args()
+ if opts.printver:
+ print(version)
+ sys.exit(0)
+
+ if not opts.product or not opts.version or not opts.release or not opts.output:
+ parser.error('Missing a required argument.')
+
+ if not args:
+ parser.error('Missing repository to use for image generation.')
+
+ lorax = pylorax.Lorax(repos=args, options=opts)
lorax.run()
-
- if cleanup:
- lorax.cleanup()
-
-
-
-# print("\n+=======================================+")
-# print("| Writing meta data to instroot tree... |")
-# print("+=======================================+\n")
-#
-# # write .treeinfo file
-# if not pylorax.treeinfo.write(family=product, variant=variant, version=version, arch=buildarch, outdir=output):
-# sys.stderr.write("Error writing %s/.treeinfo file.\n" % (output,))
-#
-# # mk-images
-# # XXX
-#
-# # write .discinfo file
-# if not pylorax.discinfo.write(release=release, arch=buildarch, outdir=output):
-# sys.stderr.write("Error writing %s/.discinfo file.\n" % (output,))
diff --git a/src/pylorax/__init__.py b/src/pylorax/__init__.py
index 46dc50a1..2acded81 100644
--- a/src/pylorax/__init__.py
+++ b/src/pylorax/__init__.py
@@ -2,7 +2,7 @@
# pylorax
# Install image and tree support data generation tool -- Python module.
#
-# Copyright (C) 2008 Red Hat, Inc.
+# Copyright (C) 2008, 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
@@ -18,120 +18,193 @@
# along with this program. If not, see .
#
# Author(s): David Cantrell
+# Martin Gracik
#
-version = (0, 1)
-
+import sys
import os
import shutil
import tempfile
+import time
+import ConfigParser
import yum
import rpmUtils
-import discinfo
-import treeinfo
+import instroot
+import images
-from instroot import InstRoot
class Lorax:
- def __init__(self, repos=[], output=None, mirrorlist=[], updates=None):
- self.conf = {}
- self.conf['confdir'] = '/etc/lorax'
- self.conf['tmpdir'] = tempfile.gettempdir()
- self.conf['datadir'] = '/usr/share/lorax'
-
+ def __init__(self, repos, options):
self.repos = repos
- self.output = output
- self.mirrorlist = mirrorlist
- self.updates = updates
+
+ # required
+ self.product = options.product
+ self.version = options.version
+ self.release = options.release
+ self.output = options.output
+
+ # optional
+ self.debug = options.debug
+ self.variant = options.variant
+ self.bugurl = options.bugurl
+ self.updates = options.updates
+ self.mirrorlist = options.mirrorlist
+ self.confdir = options.confdir
+ self.cleanup = options.cleanup
+
+ self.conf = {}
+ if not self.confdir:
+ self.confdir = '/etc/lorax'
+ self.conf['confdir'] = self.confdir
+ self.conf['datadir'] = '/usr/share/lorax'
+ self.conf['tmpdir'] = tempfile.gettempdir()
def run(self):
"""run()
Generate install images.
-
"""
- print("\n+=======================================================+")
- print("| Setting up work directories and configuration data... |")
- print("+=======================================================+\n")
+ print('Collecting repos...')
+ self.repo, self.extrarepos = self.__collectRepos()
- if repos != []:
- self.repo, self.extrarepos = self.__collectRepos(repos)
- else:
- self.repo = None
- self.extrarepos = []
+ if not self.repo:
+ sys.stderr.write('No valid repository.\n')
+ sys.exit(1)
+ print('Initializing directories...')
self.buildinstdir, self.treedir, self.cachedir = self.__initializeDirs()
+
+ print('Writing yum configuration...')
self.yumconf = self.__writeYumConf()
- print("\n+================================================+")
- print("| Creating instroot tree to build images from... |")
- print("+================================================+\n")
+ print('Getting the build architecture...')
+ self.buildarch = self.__getBuildArch()
- self.instroot = InstRoot(conf=self.conf,
- yumconf=self.yumconf,
- arch=self.getBuildArch(),
- treedir=self.treedir,
- updates=self.updates)
- self.instroot.run()
+ print('Creating install root tree...')
+ self.makeInstRoot()
- def showVersion(self, driver=None):
- """showVersion(driver)
+ print('Writing .treeinfo...')
+ self.__writeTreeInfo()
- Display program name (driver) and version number. If prog is an empty
- string or None, use the value 'pylorax'.
+ print('Writing .discinfo...')
+ self.__writeDiscInfo()
+ print('Creating images...')
+ self.makeImages()
+
+ if self.cleanup:
+ print('Cleaning up...')
+ self.cleanUp()
+
+ def __collectRepos(self):
+ """_collectRepos()
+
+ Get the main repo (the first one) and then build a list of all remaining
+ repos in the list. Sanitize each repo URL for proper yum syntax.
"""
- if prog is None or prog == '':
- prog = 'pylorax'
+ repolist = []
+ for repospec in self.repos:
+ if repospec.startswith('/'):
+ repo = 'file://%s' % (repospec,)
+ print('Adding local repo:\n %s' % (repo,))
+ repolist.append(repo)
+ elif repospec.startswith('http://') or repospec.startswith('ftp://'):
+ print('Adding remote repo:\n %s' % (repospec,))
+ repolist.append(repospec)
- print "%s version %d.%d" % (prog, version[0], version[1],)
+ if not repolist:
+ return None, []
+ else:
+ return repolist[0], repolist[1:]
- def cleanup(self, trash=[]):
- """cleanup(trash)
-
- Given a list of things to remove, cleanup() will remove them if it can.
- Never fails, just tries to remove things and returns regardless of
- failures removing things.
+ def __initializeDirs(self):
+ """_initializeDirs()
+ Create directories used for image generation.
"""
- if trash != []:
- for item in trash:
- if os.path.isdir(item):
- shutil.rmtree(item, ignore_errors=True)
- else:
- os.unlink(item)
+ if not os.path.isdir(self.output):
+ os.makedirs(self.output, mode=0755)
- if os.path.isdir(self.conf['tmpdir']):
- shutil.rmtree(self.conf['tmpdir'], ignore_errors=True)
+ self.conf['tmpdir'] = tempfile.mkdtemp('XXXXXX', 'lorax.tmp.', self.conf['tmpdir'])
+ buildinstdir = tempfile.mkdtemp('XXXXXX', 'buildinstall.tree.', self.conf['tmpdir'])
+ treedir = tempfile.mkdtemp('XXXXXX', 'treedir.', self.conf['tmpdir'])
+ cachedir = tempfile.mkdtemp('XXXXXX', 'yumcache.', self.conf['tmpdir'])
- def getBuildArch(self):
- """getBuildArch()
+ print('Working directories:')
+ print(' tmpdir = %s' % (self.conf['tmpdir'],))
+ print(' buildinstdir = %s' % (buildinstdir,))
+ print(' treedir = %s' % (treedir,))
+ print(' cachedir = %s' % (cachedir,))
+
+ return buildinstdir, treedir, cachedir
+
+ def __writeYumConf(self):
+ """_writeYumConf()
+
+ Generate a temporary yum.conf file for image generation. Returns the path
+ to the temporary yum.conf file on success, None of failure.
+ """
+
+ (fd, yumconf) = tempfile.mkstemp(prefix='yum.conf', dir=self.conf['tmpdir'])
+ f = os.fdopen(fd, 'w')
+
+ f.write('[main]\n')
+ f.write('cachedir=%s\n' % (self.cachedir,))
+ f.write('keepcache=0\n')
+ f.write('gpgcheck=0\n')
+ f.write('plugins=0\n')
+ f.write('reposdir=\n')
+ f.write('tsflags=nodocs\n\n')
+
+ f.write('[loraxrepo]\n')
+ f.write('name=lorax repo\n')
+ f.write('baseurl=%s\n' % (self.repo,))
+ f.write('enabled=1\n\n')
+
+ for n, extra in enumerate(self.extrarepos, start=1):
+ f.write('[lorax-extrarepo-%d]\n' % (n,))
+ f.write('name=lorax extra repo %d\n' % (n,))
+ f.write('baseurl=%s\n' % (extra,))
+ f.write('enabled=1\n')
+
+ for n, mirror in enumerate(self.mirrorlist, start=1):
+ f.write('[lorax-mirrorlistrepo-%d]\n' % (n,))
+ f.write('name=lorax mirrorlist repo %d\n' % (n,))
+ f.write('mirrorlist=%s\n' % (mirror,))
+ f.write('enabled=1\n')
+
+ f.close()
+ print('Wrote lorax yum configuration to %s' % (yumconf,))
+
+ return yumconf
+
+ def __getBuildArch(self):
+ """_getBuildArch()
Query the configured yum repositories to determine our build architecture,
which is the architecture of the anaconda package in the repositories.
This function is based on a subset of what repoquery(1) does.
-
"""
uname_arch = os.uname()[4]
- if self.yumconf == '' or self.yumconf is None or not os.path.isfile(self.yumconf):
- print "RETURN HERE"
+ if not self.yumconf or not os.path.isfile(self.yumconf):
+ sys.stderr.write('ERROR: yum.conf does not exist, defaulting to %s\n' % (uname_arch,))
return uname_arch
repoq = yum.YumBase()
- repoq.doConfigSetup()
+ repoq.doConfigSetup(self.yumconf)
try:
repoq.doRepoSetup()
- except yum.Errors.RepoError, e:
- sys.stderr.write("ERROR: could not query yum repository for build arch, defaulting to %s\n" % (uname_arch,))
+ except yum.Errors.RepoError:
+ sys.stderr.write('ERROR: cannot query yum repo, defaulting to %s\n' % (uname_arch,))
return uname_arch
repoq.doSackSetup(rpmUtils.arch.getArchList())
@@ -144,109 +217,80 @@ class Lorax:
ret_arch = a
break
- if ret_arch is None:
+ if not ret_arch:
ret_arch = uname_arch
- print("Building images for %s" % (ret_arch,))
-
return ret_arch
- def __collectRepos(self, repos):
- """_collectRepos(repos)
+ def __writeTreeInfo(self, discnum=1, totaldiscs=1, packagedir=''):
+ outfile = os.path.join(self.output, '.treeinfo')
- Get the main repo (the first one) and then build a list of all remaining
- repos in the list. Sanitize each repo URL for proper yum syntax.
+ data = { 'timestamp': time.time(),
+ 'family': self.product,
+ 'version': self.version,
+ 'arch': self.buildarch,
+ 'variant': self.variant,
+ 'discnum': str(discnum),
+ 'totaldiscs': str(totaldiscs),
+ 'packagedir': packagedir }
+ c = ConfigParser.ConfigParser()
+
+ section = 'general'
+ c.add_section(section)
+ for key, value in data.items():
+ c.set(section, key, value)
+
+ try:
+ f = open(outfile, 'w')
+ except IOError:
+ return False
+ else:
+ c.write(f)
+ f.close()
+ return True
+
+ def __writeDiscInfo(self, discnum=0):
+ outfile = os.path.join(self.output, '.discinfo')
+
+ try:
+ f = open(outfile, 'w')
+ except IOError:
+ return False
+ else:
+ f.write('%f\n' % (time.time(),))
+ f.write('%s\n' % (self.release,))
+ f.write('%s\n' % (self.buildarch,))
+ f.write('%d\n' % (discnum,))
+ f.close()
+ return True
+
+ def makeInstRoot(self):
+ root = instroot.InstRoot(conf=self.conf,
+ yumconf=self.yumconf,
+ arch=self.buildarch,
+ treedir=self.treedir,
+ updates=self.updates)
+ root.run()
+
+ # TODO
+ def makeImages(self):
+ pass
+
+ def cleanUp(self, trash=[]):
+ """cleanup([trash])
+
+ Given a list of things to remove, cleanUp() will remove them if it can.
+ Never fails, just tries to remove things and returns regardless of
+ failures removing things.
"""
- if repos is None or repos == []:
- return '', []
+ for item in trash:
+ if os.path.isdir(item):
+ shutil.rmtree(item, ignore_errors=True)
+ else:
+ os.unlink(item)
- repolist = []
- for repospec in repos:
- if repospec.startswith('/'):
- repo = "file://%s" % (repospec,)
- print("Adding local repo:\n %s" % (repo,))
- repolist.append(repo)
- elif repospec.startswith('http://') or repospec.startswith('ftp://'):
- print("Adding remote repo:\n %s" % (repospec,))
- repolist.append(repospec)
+ if os.path.isdir(self.conf['tmpdir']):
+ shutil.rmtree(self.conf['tmpdir'], ignore_errors=True)
- repo = repolist[0]
- extrarepos = []
-
- if len(repolist) > 1:
- for extra in repolist[1:]:
- print("Adding extra repo:\n %s" % (extra,))
- extrarepos.append(extra)
-
- return repo, extrarepos
-
- def __initializeDirs(self):
- """_initializeDirs()
-
- Create directories used for image generation.
-
- """
-
- if not os.path.isdir(self.output):
- os.makedirs(self.output, mode=0755)
-
- self.conf['tmpdir'] = tempfile.mkdtemp('XXXXXX', 'lorax.tmp.', self.conf['tmpdir'])
- buildinstdir = tempfile.mkdtemp('XXXXXX', 'buildinstall.tree.', self.conf['tmpdir'])
- treedir = tempfile.mkdtemp('XXXXXX', 'treedir.', self.conf['tmpdir'])
- cachedir = tempfile.mkdtemp('XXXXXX', 'yumcache.', self.conf['tmpdir'])
-
- print("Working directories:")
- print(" tmpdir = %s" % (self.conf['tmpdir'],))
- print(" buildinstdir = %s" % (buildinstdir,))
- print(" treedir = %s" % (treedir,))
- print(" cachedir = %s" % (cachedir,))
-
- return buildinstdir, treedir, cachedir
-
- def __writeYumConf(self):
- """_writeYumConf()
-
- Generate a temporary yum.conf file for image generation. Returns the path
- to the temporary yum.conf file on success, None of failure.
- """
-
- tmpdir = self.conf['tmpdir']
- (fd, yumconf) = tempfile.mkstemp(prefix='yum.conf', dir=tmpdir)
- f = os.fdopen(fd, 'w')
-
- f.write("[main]\n")
- f.write("cachedir=%s\n" % (self.cachedir,))
- f.write("keepcache=0\n")
- f.write("gpgcheck=0\n")
- f.write("plugins=0\n")
- f.write("reposdir=\n")
- f.write("tsflags=nodocs\n\n")
- f.write("[loraxrepo]\n")
- f.write("name=lorax repo\n")
- f.write("baseurl=%s\n" % (self.repo,))
- f.write("enabled=1\n\n")
-
- if self.extrarepos != []:
- n = 1
- for extra in self.extrarepos:
- f.write("[lorax-extrarepo-%d]\n" % (n,))
- f.write("name=lorax extra repo %d\n" % (n,))
- f.write("baseurl=%s\n" % (extra,))
- f.write("enabled=1\n")
- n += 1
-
- if self.mirrorlist != []:
- n = 1
- for mirror in self.mirrorlist:
- f.write("[lorax-mirrorlistrepo-%d]\n" % (n,))
- f.write("name=lorax mirrorlist repo %d\n" % (n,))
- f.write("mirrorlist=%s\n" % (mirror,))
- f.write("enabled=1\n")
- n += 1
-
- f.close()
- print("Wrote lorax yum configuration to %s" % (yumconf,))
-
- return yumconf
diff --git a/src/pylorax/discinfo.py b/src/pylorax/discinfo.py
deleted file mode 100644
index f9aa7e28..00000000
--- a/src/pylorax/discinfo.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# pylorax discinfo module
-# Install image and tree support data generation tool -- Python module.
-#
-# Copyright (C) 2008 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 .
-#
-# Author(s): David Cantrell
-#
-
-import os
-import time
-
-# Write out the .discinfo file
-def write(release=None, arch=None, outdir=None, disc=None):
- """write(release=None, arch=None, outdir=None, [disc=None])
-
- Write the .discinfo file to the specified directory (outdir).
- The release string is specified as release and the architecture
- is specified as arch. If disc is specified, it will be written
- as the disc number, otherwise 0 is written for the disc number.
-
- The release, arch, and outdir parameters are all required.
-
- """
-
- if release is None or arch is None or outdir is None:
- return False
-
- if not os.path.isdir(outdir):
- return False
-
- outfile = "%s/.discinfo" % (outdir,)
-
- try:
- f = open(outfile, "w")
- f.write("%s\n", time.time())
- f.write("%s\n", release)
- f.write("%s\n", arch)
-
- if disc is not None:
- f.write("%d\n", disc)
- else:
- f.write("0\n")
-
- f.close()
- except:
- return False
-
- return True
diff --git a/src/pylorax/fileutils.py b/src/pylorax/fileutils.py
new file mode 100644
index 00000000..ec1e1edb
--- /dev/null
+++ b/src/pylorax/fileutils.py
@@ -0,0 +1,50 @@
+import os
+import shutil
+import glob
+
+
+def cp(src, dst, verbose=False):
+ for name in glob.iglob(src):
+ __copy(name, dst, verbose=verbose)
+
+def mv(src, dst, verbose=False):
+ for name in glob.iglob(src):
+ __copy(name, dst, verbose=verbose, remove=True)
+
+
+def __copy(src, dst, verbose=False, remove=False):
+ if not os.path.exists(src):
+ print('cannot stat "%s": No such file or directory' % (src,))
+ return
+
+ if os.path.isdir(dst):
+ basename = os.path.basename(src)
+ dst = os.path.join(dst, basename)
+
+ if os.path.isdir(src):
+ if os.path.isfile(dst):
+ print('omitting directory "%s"' % (src,))
+ return
+
+ if not os.path.isdir(dst):
+ os.makedirs(dst)
+
+ names = map(lambda name: os.path.join(src, name), os.listdir(src))
+ for name in names:
+ __copy(name, dst, verbose=verbose, remove=remove)
+ else:
+ if os.path.isdir(dst):
+ print('cannot overwrite directory "%s" with non-directory' % (dst,))
+ return
+
+ try:
+ if verbose:
+ print('copying "%s" to "%s"' % (src, dst))
+ shutil.copy2(src, dst)
+ except shutil.Error, IOError:
+ print('cannot copy "%s" to "%s"' % (src, dst))
+ else:
+ if remove:
+ if verbose:
+ print('removing "%s"' % (src,))
+ os.unlink(src)
diff --git a/src/pylorax/images.py b/src/pylorax/images.py
new file mode 100644
index 00000000..3394cb80
--- /dev/null
+++ b/src/pylorax/images.py
@@ -0,0 +1,102 @@
+#
+# pylorax images module
+# Install image and tree support data generation tool -- Python module
+#
+
+import datetime
+
+
+class Images():
+
+ def __init__(self, conf, yumconf, arch, imgdir, product, version, bugurl, output, noiso=False):
+ self.conf = conf
+ self.yumconf = yumconf
+
+ self.arch = arch
+ self.imgdir = imgdir
+ self.product = product
+ self.version = version
+ self.bugurl = bugurl
+
+ self.output = output
+ self.noiso = noiso
+
+ now = datetime.datetime.now()
+ self.imageuuid = now.strftime('%Y%m%d%H%M') + '.' + os.uname()[4]
+
+ self.initrdmods = self.__getModulesList()
+
+ if self.arch == 'sparc64':
+ self.basearch = 'sparc'
+ else:
+ self.basearch = self.arch
+
+ self.libdir = 'lib'
+ if self.arch == 'x86_64' or self.arch =='s390x':
+ self.libdir = 'lib64'
+
+ # explicit block size setting for some arches
+ # FIXME we compose ppc64-ish trees as ppc, so we have to set the "wrong" block size
+ # XXX i don't get this :)
+ self.crambs = []
+ if self.arch == 'sparc64':
+ self.crambs = ['--blocksize', '8192']
+ elif self.arch == 'sparc':
+ self.crambs = ['--blocksize', '4096']
+
+ self.__setUpDirectories()
+
+ def __getModulesList(self):
+ modules = set()
+
+ modules_files = []
+ modules_files.append(os.path.join(self.conf['confdir'], 'modules'))
+ modules_files.append(os.path.join(self.conf['confdir'], self.arch, 'modules'))
+
+ for pfile in modules_files:
+ if os.path.isfile(pfile):
+ f = open(pfile, 'r')
+ for line in f.readlines():
+ line = line.strip()
+
+ if not line or line.startswith('#'):
+ continue
+
+ if line.startswith('-'):
+ modules.discard(line[1:])
+ else:
+ modules.add(line)
+
+ f.close()
+
+ modules = list(modules)
+ modules.sort()
+
+ return modules
+
+ def __setUpDirectories(self):
+ imagepath = os.path.join(self.output, 'images')
+ fullmodpath = tempfile.mkdtemp('XXXXXX', 'instimagemods.', self.conf['tmpdir'])
+ finalfullmodpath = os.path.join(self.output, 'modules')
+
+ kernelbase = tempfile.mkdtemp('XXXXXX', 'updboot.kernel.', self.conf['tmpdir'])
+ kernelname = 'vmlinuz'
+
+ kerneldir = '/boot'
+ if self.arch == 'ia64':
+ kerneldir = os.path.join(kerneldir, 'efi', 'EFI', 'redhat')
+
+ for dir in [imagepath, fullmodpath, finalfullmodpath, kernelbase]:
+ if os.path.isdir(dir):
+ shutil.rmtree(dir)
+ os.makedirs(dir)
+
+ self.imagepath = imagepath
+ self.fullmodpath = fullmodpath
+ self.finalfullmodpath = finalfullmodpath
+
+ self.kernelbase = kernelbase
+ self.kernelname = kernelname
+ self.kerneldir = kerneldir
+
+
diff --git a/src/pylorax/instroot.py b/src/pylorax/instroot.py
index ee04c854..00b00db3 100644
--- a/src/pylorax/instroot.py
+++ b/src/pylorax/instroot.py
@@ -2,7 +2,7 @@
# pylorax instroot module
# Install image and tree support data generation tool -- Python module.
#
-# Copyright (C) 2008 Red Hat, Inc.
+# Copyright (C) 2008, 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
@@ -18,53 +18,57 @@
# along with this program. If not, see .
#
# Author(s): David Cantrell
+# Martin Gracik
#
-import glob
-import os
-import shutil
import sys
+import os
+import stat
+import shutil
+import glob
+import fnmatch
+import re
+import fileinput
+import subprocess
+
+import pwd
+import grp
+
+from fileutils import cp, mv
sys.path.insert(0, '/usr/share/yum-cli')
import yummain
class InstRoot:
- """InstRoot(conf=None, yumconf=None, arch=None, treedir=None, [updates=None])
+ """InstRoot(conf, yumconf, arch, treedir, [updates=None])
Create a instroot tree for the specified architecture. The list of
packages to install are specified in the /etc/lorax/packages and
/etc/lorax/ARCH/packages files.
- yumconf is the path to the yum configuration create for this run of
+ yumconf is the path to the yum configuration file created for this run of
lorax. arch is the platform name we are building for, treedir is
the location where the instroot tree should go
(will be treedir + '/install'). updates is an optional path to a
- directory of update RPM packages for the instroot.
+ directory of updated RPM packages for the instroot.
- The yumconf, arch, and treedir parameters are all required.
+ The conf, yumconf, arch, and treedir parameters are all required.
On success, this function returns True. On failure, False is
returned or the program is aborted immediately.
-
"""
- # Create inst root from which stage 1 and stage 2 images are built.
- def __init__(self, conf=None, yumconf=None, arch=None, treedir=None, updates=None):
+ def __init__(self, conf, yumconf, arch, treedir, updates=None):
self.conf = conf
self.yumconf = yumconf
self.arch = arch
self.treedir = treedir
self.updates = updates
- # XXX: these tests should raise exceptions
- if yumconf is None or arch is None or treedir is None:
- return False
-
+ self.libdir = 'lib'
# on 64-bit systems, make sure we use lib64 as the lib directory
if self.arch.endswith('64') or self.arch == 's390x':
self.libdir = 'lib64'
- else:
- self.libdir = 'lib'
# the directory where the instroot will be created
self.destdir = os.path.join(self.treedir, 'install')
@@ -73,7 +77,6 @@ class InstRoot:
"""run()
Generate the instroot tree and prepare it for building images.
-
"""
if not os.path.isdir(self.destdir):
@@ -101,14 +104,11 @@ class InstRoot:
for line in f.readlines():
line = line.strip()
- if line.startswith('#') or line == '':
+ if not line or line.startswith('#'):
continue
if line.startswith('-'):
- try:
- packages.remove(line[1:])
- except KeyError:
- pass
+ packages.discard(line[1:])
else:
packages.add(line)
@@ -119,64 +119,83 @@ class InstRoot:
return packages
- # Call yummain to install the list of packages to destdir
def __installPackages(self):
# build the list of arguments to pass to yum
arglist = ['-c', self.yumconf]
arglist.append("--installroot=%s" % (self.destdir,))
- arglist += ['install', '-y'] + self.packages
+ arglist.extend(['install', '-y'])
+ arglist.extend(self.packages)
# do some prep work on the destdir before calling yum
+ os.makedirs(os.path.join(self.destdir, 'boot'))
+ os.makedirs(os.path.join(self.destdir, 'usr', 'sbin'))
os.makedirs(os.path.join(self.destdir, 'usr', 'lib', 'debug'))
os.makedirs(os.path.join(self.destdir, 'usr', 'src', 'debug'))
os.makedirs(os.path.join(self.destdir, 'tmp'))
os.makedirs(os.path.join(self.destdir, 'var', 'log'))
os.makedirs(os.path.join(self.destdir, 'var', 'lib'))
+ os.makedirs(os.path.join(self.destdir, 'var', 'lib', 'yum'))
os.symlink(os.path.join(os.path.sep, 'tmp'), os.path.join(self.destdir, 'var', 'lib', 'xkb'))
- # XXX: sort through yum errcodes and return False for actual bad things
- # we care about
+ # XXX sort through yum errcodes and return False for actual bad things we care about
errcode = yummain.user_main(arglist, exit_code=False)
- # Scrub the instroot tree (remove files we don't want, modify settings, etc)
- def __scrubInstRoot(self):
- print
+ # copy updates to destdir
+ if self.updates and os.path.isdir(self.updates):
+ cp(os.path.join(self.updates, '*'), self.destdir)
- # drop custom configuration files in to the instroot
- dogtailconf = os.path.join(self.conf['datadir'], 'dogtail-%conf.xml')
+ def __scrubInstRoot(self):
+ self.__createConfigFiles()
+ self.__removeGtkThemes()
+ self.__removeLocales()
+ self.__fixManPages()
+ self.__installStubs()
+ self.__copyBootloaders()
+ self.__moveYumRepos()
+ self.__configureKmod()
+ self.__moveAnacondaFiles()
+ self.__setShellLinks()
+ self.__moveBins()
+ self.__removeUnwanted()
+ self.__changeDestDirPermissions()
+ self.__createLDConfig()
+ self.__setBusyboxLinks()
+ self.__strip()
+ self.__fixBrokenLinks()
+
+ def __createConfigFiles(self):
+ # create %gconf.xml
+ dogtailconf = os.path.join(self.conf['datadir'], 'dogtail-%gconf.xml')
if os.path.isfile(dogtailconf):
- os.makedirs(os.path.join(destdir, '.gconf', 'desktop', 'gnome', 'interface'))
- f = open(os.path.join(destdir, '.gconf', 'desktop', '%gconf.xml'), 'w')
+ os.makedirs(os.path.join(self.destdir, '.gconf', 'desktop', 'gnome', 'interface'))
+ f = open(os.path.join(self.destdir, '.gconf', 'desktop', '%gconf.xml'), 'w')
f.close()
- f = open(os.path.join(destdir, '.gconf', 'desktop', 'gnome', '%gconf.xml'), 'w')
+ f = open(os.path.join(self.destdir, '.gconf', 'desktop', 'gnome', '%gconf.xml'), 'w')
f.close()
- dest = os.path.join(destdir, '.gconf', 'desktop', 'gnome', 'interface', '%gconf.xml')
- print "Installing %s..." % (os.path.join(os.path.sep, '.gconf', 'desktop', 'gnome', 'interface', '%gconf.xml'),)
- shutil.copy(dogtailconf, dest)
+ dst = os.path.join(self.destdir, '.gconf', 'desktop', 'gnome', 'interface', '%gconf.xml')
+ cp(dogtailconf, dst)
# create selinux config
if os.path.isfile(os.path.join(self.destdir, 'etc', 'selinux', 'targeted')):
- src = os.path.join(self.conf['datadir'], 'selinux-config')
- if os.path.isfile(src):
- dest = os.path.join(self.destdir, 'etc', 'selinux', 'config')
- print "Installing %s..." % (os.path.join(os.path.sep, 'etc', 'selinux', 'config'),)
- shutil.copy(src, dest)
+ selinuxconf = os.path.join(self.conf['datadir'], 'selinux-config')
+ if os.path.isfile(selinuxconf):
+ dst = os.path.join(self.destdir, 'etc', 'selinux', 'config')
+ cp(selinuxconf, dst)
# create libuser.conf
- src = os.path.join(self.conf['datadir'], 'libuser.conf')
- dest = os.path.join(self.destdir, 'etc', 'libuser.conf')
- if os.path.isfile(src):
- print "Installing %s..." % (os.path.join(os.path.sep, 'etc', 'libuser.conf'),)
- shutil.copy(src, dest)
+ libuserconf = os.path.join(self.conf['datadir'], 'libuser.conf')
+ if os.path.isfile(libuserconf):
+ dst = os.path.join(self.destdir, 'etc', 'libuser.conf')
+ cp(libuserconf, dst)
+ def __removeGtkThemes(self):
# figure out the gtk+ theme to keep
gtkrc = os.path.join(self.destdir, 'etc', 'gtk-2.0', 'gtkrc')
gtk_theme_name = None
- gtk_icon_themes = []
gtk_engine = None
+ gtk_icon_themes = []
if os.path.isfile(gtkrc):
- print "\nReading %s..." % (os.path.join(os.path.sep, 'etc', 'gtk-2.0', 'gtkrc'),)
f = open(gtkrc, 'r')
lines = f.readlines()
f.close()
@@ -184,11 +203,12 @@ class InstRoot:
for line in lines:
line = line.strip()
if line.startswith('gtk-theme-name'):
- gtk_theme_name = line[line.find('=') + 1:].replace('"', '').strip()
- print " gtk-theme-name: %s" % (gtk_theme_name,)
+ gtk_theme_name = line[line.find('=') + 1:]
+ gtk_theme_name = gtk_theme_name.replace('"', '').strip()
# find the engine for this theme
- gtkrc = os.path.join(self.destdir, 'usr', 'share', 'themes', gtk_theme_name, 'gtk-2.0', 'gtkrc')
+ gtkrc = os.path.join(self.destdir, 'usr', 'share', 'themes',
+ gtk_theme_name, 'gtk-2.0', 'gtkrc')
if os.path.isfile(gtkrc):
f = open(gtkrc, 'r')
engine_lines = f.readlines()
@@ -196,19 +216,20 @@ class InstRoot:
for engine_line in engine_lines:
engine_line = engine_line.strip()
-
if engine_line.find('engine') != -1:
- gtk_engine = engine_line[engine_line.find('"') + 1:].replace('"', '')
- print " gtk-engine: %s" % (gtk_engine,)
+ gtk_engine = engine_line[engine_line.find('"') + 1:]
+ gtk_engine = gtk_engine.replace('"', '').strip()
break
+
elif line.startswith('gtk-icon-theme-name'):
- icon_theme = line[line.find('=') + 1:].replace('"', '').strip()
- print " gtk-icon-theme-name: %s" % (icon_theme,)
+ icon_theme = line[line.find('=') + 1:]
+ icon_theme = icon_theme.replace('"', '').strip()
gtk_icon_themes.append(icon_theme)
# bring in all inherited themes
while True:
- icon_theme_index = os.path.join(self.destdir, 'usr', 'share', 'icons', icon_theme, 'index.theme')
+ icon_theme_index = os.path.join(self.destdir, 'usr', 'share', 'icons',
+ icon_theme, 'index.theme')
if os.path.isfile(icon_theme_index):
inherits = False
f = open(icon_theme_index, 'r')
@@ -219,8 +240,8 @@ class InstRoot:
icon_line = icon_line.strip()
if icon_line.startswith('Inherits='):
inherits = True
- icon_theme = icon_line[icon_line.find('=') + 1:].replace('"', '')
- print " inherits gtk-icon-theme-name: %s" % (icon_theme,)
+ icon_theme = icon_line[icon_line.find('=') + 1:]
+ icon_theme = icon_theme.replace('"', '').strip()
gtk_icon_themes.append(icon_theme)
break
@@ -229,34 +250,32 @@ class InstRoot:
else:
break
- theme_path = os.path.join(self.estdir, 'usr', 'share', 'themes')
+ # remove themes we don't need
+ theme_path = os.path.join(self.destdir, 'usr', 'share', 'themes')
if os.path.isdir(theme_path):
- for theme in os.listdir(theme_path):
- if theme != gtk_theme_name:
- theme = os.path.join(theme_path, theme)
- shutil.rmtree(theme, ignore_errors=True)
+ for theme in filter(lambda theme: theme != gtk_theme_name, os.listdir(theme_path)):
+ theme = os.path.join(theme_path, theme)
+ shutil.rmtree(theme, ignore_errors=True)
+ # remove icons we don't need
icon_path = os.path.join(self.destdir, 'usr', 'share', 'icons')
if os.path.isdir(icon_path):
- for icon in os.listdir(icon_path):
- try:
- if gtk_icon_themes.index(icon):
- continue
- except ValueError:
- icon = os.path.join(icon_path, icon)
- shutil.rmtree(icon, ignore_errors=True)
+ for icon in filter(lambda icon: icon not in gtk_icon_themes, os.listdir(icon_path)):
+ icon = os.path.join(icon_path, icon)
+ shutil.rmtree(icon, ignore_errors=True)
- tmp_path = os.path.join(self.destdir, 'usr', libdir, 'gtk-2.0')
+ # remove engines we don't need
+ tmp_path = os.path.join(self.destdir, 'usr', self.libdir, 'gtk-2.0')
if os.path.isdir(tmp_path):
- for subdir in os.listdir(tmp_path):
- new_path = os.path.join(tmp_path, subdir, 'engines')
- if os.path.isdir(new_path):
- for engine in os.listdir(new_path):
- if engine.find(gtk_engine) == -1:
- tmp_engine = os.path.join(new_path, engine)
- os.unlink(tmp_engine)
+ fnames = map(lambda fname: os.path.join(tmp_path, fname, 'engines'), os.listdir(tmp_path))
+ dnames = filter(lambda fname: os.path.isdir(fname), fnames)
+ for dir in dnames:
+ engines = filter(lambda engine: engine.find(gtk_engine) == -1, os.listdir(dir))
+ for engine in engines:
+ engine = os.path.join(dir, engine)
+ os.unlink(engine)
- # clean out unused locales
+ def __removeLocales(self):
langtable = os.path.join(self.destdir, 'usr', 'lib', 'anaconda', 'lang-table')
localepath = os.path.join(self.destdir, 'usr', 'share', 'locale')
if os.path.isfile(langtable):
@@ -267,11 +286,9 @@ class InstRoot:
lines = f.readlines()
f.close()
- print "Keeping locales used during installation..."
for line in lines:
line = line.strip()
-
- if line == '' or line.startswith('#'):
+ if not line or line.startswith('#'):
continue
fields = line.split('\t')
@@ -283,23 +300,40 @@ class InstRoot:
if os.path.isdir(os.path.join(localepath, locale)):
locales.add(locale)
- for locale in os.listdir(os.path.join(self.destdir, 'usr', 'share', 'locale')):
+ for locale in os.listdir(localepath):
all_locales.add(locale)
- print "Removing unused locales..."
locales_to_remove = list(all_locales.difference(locales))
for locale in locales_to_remove:
- rmpath = os.path.join(self.destdir, 'usr', 'share', 'locale', locale)
+ rmpath = os.path.join(localepath, locale)
shutil.rmtree(rmpath, ignore_errors=True)
- # fix up some links for man page related stuff
+ def __fixManPages(self):
for file in ['nroff', 'groff', 'iconv', 'geqn', 'gtbl', 'gpic', 'grefer']:
src = os.path.join('mnt', 'sysimage', 'usr', 'bin', file)
dst = os.path.join(self.destdir, 'usr', 'bin', file)
if not os.path.isfile(dst):
os.symlink(src, dst)
- # install anaconda stub programs as instroot programs
+ # fix /etc/man.config to point to /mnt/sysimage
+ manconfig = os.path.join(self.destdir, 'etc', 'man.config')
+
+ # XXX WHY?
+ # don't change MANPATH_MAP lines now
+ fin = fileinput.input(manconfig, inplace=1)
+ for line in fin:
+ line = re.sub(r'^MANPATH[^_MAP][ \t]*', r'&/mnt/sysimage', line)
+ sys.stdout.write(line)
+ fin.close()
+
+ # change MANPATH_MAP lines
+ fin = fileinput.input(manconfig, inplace=1)
+ for line in fin:
+ line = re.sub(r'^MANPATH_MAP[ \t]*[a-zA-Z0-9/]*[ \t]*', r'&/mnt/sysimage', line)
+ sys.stdout.write(line)
+ fin.close()
+
+ def __installStubs(self):
for subdir in ['lib', 'firmware']:
subdir = os.path.join(self.destdir, subdir)
if not os.path.isdir(subdir):
@@ -311,56 +345,299 @@ class InstRoot:
shutil.rmtree(dst, ignore_errors=True)
os.symlink(src, dst)
- for prog in ['raidstart', 'raidstop', 'losetup', 'list-harddrives', 'loadkeys', 'mknod', 'sysklogd']:
+ for prog in ['raidstart', 'raidstop', 'losetup', 'list-harddrives', 'loadkeys', 'mknod',
+ 'syslogd']:
stub = "%s-stub" % (prog,)
src = os.path.join(self.destdir, 'usr', 'lib', 'anaconda', stub)
dst = os.path.join(self.destdir, 'usr', 'bin', prog)
if os.path.isfile(src) and not os.path.isfile(dst):
- shutil.copy2(src, dst)
+ cp(src, dst)
- # copy in boot loader files
+ def __copyBootloaders(self):
bootpath = os.path.join(self.destdir, 'usr', 'lib', 'anaconda-runtime', 'boot')
if not os.path.isdir(bootpath):
os.makedirs(bootpath)
- if arch == 'i386' or arch == 'x86_64':
+ if self.arch == 'i386' or self.arch == 'x86_64':
for bootfile in os.listdir(os.path.join(self.destdir, 'boot')):
if bootfile.startswith('memtest'):
src = os.path.join(self.destdir, 'boot', bootfile)
dst = os.path.join(bootpath, bootfile)
- shutil.copy2(src, dst)
- elif arch.startswith('sparc'):
+ cp(src, dst)
+ elif self.arch.startswith('sparc'):
for bootfile in os.listdir(os.path.join(self.destdir, 'boot')):
if bootfile.endswith('.b'):
src = os.path.join(self.destdir, 'boot', bootfile)
dst = os.path.join(bootpath, bootfile)
- shutil.copy2(src, dst)
- elif arch.startswith('ppc'):
+ cp(src, dst)
+ elif self.arch.startswith('ppc'):
src = os.path.join(self.destdir, 'boot', 'efika.forth')
dst = os.path.join(bootpath, 'efika.forth')
- shutil.copy2(src, dst)
- elif arch == 'alpha':
+ cp(src, dst)
+ elif self.arch == 'alpha':
src = os.path.join(self.destdir, 'boot', 'bootlx')
dst = os.path.join(bootpath, 'bootlx')
- shutil.copy2(src, dst)
- elif arch == 'ia64':
+ cp(src, dst)
+ elif self.arch == 'ia64':
src = os.path.join(self.destdir, 'boot', 'efi', 'EFI', 'redhat')
shutil.rmtree(bootpath, ignore_errors=True)
- shutil.copytree(src, bootpath)
+ cp(src, bootpath)
- # move the yum repos configuration directory
+ def __moveYumRepos(self):
src = os.path.join(self.destdir, 'etc', 'yum.repos.d')
dst = os.path.join(self.destdir, 'etc', 'anaconda.repos.d')
if os.path.isdir(src):
shutil.rmtree(dst, ignore_errors=True)
- shutil.move(src, dst)
+ mv(src, dst)
- # remove things we do not want in the instroot
+ def __configureKmod(self):
+ fedorakmodconf = os.path.join(self.destdir, 'etc', 'yum', 'pluginconf.d', 'fedorakmod.conf')
+
+ # XXX this file does not exist, what package provides it?
+ if not os.path.exists(fedorakmodconf):
+ return
+
+ fin = fileinput.input(fedorakmodconf, inplace=1)
+ for line in fin:
+ line = re.sub(r'\(installforallkernels\) = 0', r'\1 = 1', line)
+ sys.stdout.write(line)
+ fin.close()
+
+ def __moveAnacondaFiles(self):
+ # move executable
+ src = os.path.join(self.destdir, 'usr', 'sbin', 'anaconda')
+ dst = os.path.join(self.destdir, 'usr', 'bin', 'anaconda')
+ mv(src, dst)
+
+ # move libraries
+ src = os.path.join(self.destdir, 'usr', 'lib', 'anaconda-runtime', 'lib')
+ dst = os.path.join(self.destdir, 'usr', self.libdir)
+ for fname in glob.glob(src + '*'):
+ mv(fname, dst)
+
+ def __setShellLinks(self):
+ bash = os.path.join(self.destdir, 'bin', 'bash')
+ ash = os.path.join(self.destdir, 'bin', 'ash')
+ sh = os.path.join(self.destdir, 'bin', 'sh')
+ busybox = os.path.join(self.destdir, 'bin', 'busybox')
+
+ if os.path.exists(bash):
+ # XXX is this needed? i don't have ash in the tree...
+ try:
+ os.unlink(ash)
+ except OSError:
+ pass
+
+ os.unlink(sh)
+ os.symlink(bash, sh)
+ else:
+ os.unlink(sh)
+ os.symlink(busybox, sh)
+
+ def __moveBins(self):
+ bin = os.path.join(self.destdir, 'bin')
+ sbin = os.path.join(self.destdir, 'sbin')
+
+ if not os.path.exists(bin) or not os.path.exists(sbin):
+ raise Error, 'bin or sbin directory missing'
+
+ dst = os.path.join(self.destdir, 'usr')
+ for src in (bin, sbin):
+ mv(src, dst)
+
+ def __removeUnwanted(self):
for subdir in ['boot', 'home', 'root', 'tmp']:
shutil.rmtree(os.path.join(self.destdir, subdir), ignore_errors=True)
for subdir in ['doc', 'info']:
shutil.rmtree(os.path.join(self.destdir, 'usr', 'share', subdir), ignore_errors=True)
- for libname in glob.glob(os.path.join(self.destdir, 'usr', libdir), 'libunicode-lite*'):
+ for libname in glob.glob(os.path.join(self.destdir, 'usr', self.libdir, 'libunicode-lite*')):
shutil.rmtree(libname, ignore_errors=True)
+
+ to_remove = set()
+ for root, files, dirs in os.walk(self.destdir):
+ for file in files:
+ path = os.path.join(root, file)
+ if fnmatch.fnmatch(path, '*.a'):
+ if path.find('kernel-wrapper/wrapper.a') == -1:
+ to_remove.append(path)
+ elif fnmatch.fnmatch(path, 'lib*.la'):
+ if path.find('usr/' + self.libdir + '/gtk-2.0') == -1:
+ to_remove.append(path)
+ elif fnmatch.fnmatch(path, '*.py'):
+ to_remove.append(path + 'o')
+ to_remove.append(path + 'c')
+ os.symlink('/dev/null', path + 'c')
+
+ for file in to_remove:
+ if os.path.isdir(file):
+ shutil.rmtree(file)
+ else:
+ os.unlink(file)
+
+ # nuke some python stuff we don't need
+ for fname in ['idle', 'distutils', 'bsddb', 'lib-old', 'hotshot', 'doctest.py', 'pydoc.py',
+ 'site-packages/japanese', 'site-packages/japanese.pth']:
+ path = os.path.join(self.destdir, fname)
+ if os.path.isdir(path):
+ shutil.rmtree(path)
+ else:
+ try:
+ os.unlink(path)
+ except OSError:
+ pass
+
+ for fname in ['distutils', 'lib-dynload/japanese', 'encodings', 'compiler', 'email/test',
+ 'curses', 'pydoc.py']:
+ path = os.path.join(self.destdir, 'usr', self.libdir, 'python?.?', 'site-packages',
+ fname)
+ for item in glob.glob(path):
+ if os.path.isdir(item):
+ shutil.rmtree(item)
+ else:
+ os.unlink(item)
+
+ def __changeDestDirPermissions(self):
+ root_uid = pwd.getpwnam('root')[2]
+ root_gid = grp.getgrnam('root')[2]
+
+ for root, files, dirs in os.walk(self.destdir):
+ os.chown(root, root_uid, root_gid)
+ os.chmod(root, 0755)
+
+ for file in files:
+ path = os.path.join(root, file)
+ os.chown(path, root_uid, root_gid)
+
+ mode = os.stat(path).st_mode
+ if (mode & stat.S_IXUSR) or (mode & stat.S_IXGRP) or (mode & stat.S_IXOTH):
+ os.chmod(path, 0555)
+ else:
+ os.chmod(path, 0444)
+
+ def __createLDConfig(self):
+ ldsoconf = os.path.join(self.destdir, 'etc', 'ld.so.conf')
+ f = open(ldsoconf, 'w')
+ f.close()
+
+ proc_dir = os.path.join(self.destdir, 'proc')
+ if not os.path.isdir(proc_dir):
+ os.makedirs(proc_dir)
+
+ # XXX isn't there a better way?
+ os.system('mount -t proc proc %s' % (proc_dir,))
+
+ f = open(ldsoconf, 'w')
+ x11_libdir = os.path.join(self.destdir, 'usr', 'X11R6', self.libdir)
+ if os.path.exists(x11_libdir):
+ f.write('/usr/X11R6/%s\n' % (self.libdir,))
+ f.write('/usr/kerberos/%s\n' % (self.libdir,))
+
+ cwd = os.getcwd()
+ os.chdir(self.destdir)
+ # XXX can't exit from os.chroot() :(
+ os.system('/usr/sbin/chroot %s /usr/sbin/ldconfig' % (self.destdir,))
+ os.chdir(cwd)
+
+ if self.arch not in ('s390', 's390x'):
+ os.unlink(os.path.join(self.destdir, 'usr', 'sbin', 'ldconfig'))
+
+ os.unlink(os.path.join(self.destdir, 'etc', 'ld.so.conf'))
+
+ # XXX isn't there a better way?
+ os.system('umount %s' % (proc_dir,))
+
+ def __setBusyboxLinks(self):
+ src = os.path.join(self.destdir, 'usr', 'sbin', 'busybox.anaconda')
+ dst = os.path.join(self.destdir, 'usr', 'bin', 'busybox')
+ mv(src, dst)
+
+ cwd = os.getcwd()
+ os.chdir(os.path.join(self.destdir, 'usr', 'bin'))
+
+ busybox_process = subprocess.Popen(['./busybox'], stdout=subprocess.PIPE)
+ busybox_process.wait()
+
+ if busybox_process.returncode:
+ raise LoraxError, 'cannot run busybox'
+
+ busybox_output = busybox_process.stdout.readlines()
+ busybox_output = map(lambda line: line.strip(), busybox_output)
+ busybox_output = busybox_output[busybox_output.index('Currently defined functions:') + 1:]
+
+ commands = []
+ for line in busybox_output:
+ commands.extend(map(lambda c: c.strip(), line.split(',')))
+
+ # remove empty strings
+ commands = filter(lambda c: c, commands)
+
+ for command in commands:
+ # XXX why do we skip these commands? can "busybox" be there at all?
+ if command not in ['buxybox', 'sh', 'shutdown', 'poweroff', 'reboot']:
+ if not os.path.exists(command):
+ os.symlink('busybox', command)
+
+ os.chdir(cwd)
+
+ def __strip(self):
+ # XXX is this thing really needed? it's ugly
+ fnames = map(lambda fname: os.path.join(self.destdir, fname), os.listdir(self.destdir))
+ fnames = filter(lambda fname: os.path.isfile(fname), fnames)
+
+ executables = []
+ xmodules = os.path.join('usr', 'X11R6', self.libdir, 'modules')
+ for fname in fnames:
+ if not fname.find(xmodules) == -1:
+ continue
+
+ mode = os.stat(fname).st_mode
+ if (mode & stat.S_IXUSR):
+ executables.append(fname)
+
+ elfs = []
+ for exe in executables:
+ p = subprocess.Popen(['file', exe], stdout=subprocess.PIPE)
+ p.wait()
+
+ output = p.stdout.readlines()
+ output = ''.join(output)
+ if re.match(r'^[^:]*:.*ELF.*$', output):
+ elfs.append(exe)
+
+ for elf in elfs:
+ p = subprocess.Popen(['objdump', '-h', elf], stdout=subprocess.PIPE)
+ p.wait()
+
+ cmd = ['strip']
+ if self.arch == 'ia64':
+ cmd.append('--strip-debug')
+
+ arglist = [elf, '-R', '.comment', '-R', '.note']
+ for line in p.stdout.readlines():
+ m = re.match(r'^.*(?P\.gnu\.warning\.[^ ]*) .*$', line)
+ if m:
+ arglist.extend(['-R', m.group('warning')])
+
+ p = subprocess.Popen(cmd + arglist)
+ p.wait()
+
+ def __fixBrokenLinks(self):
+ for dir in ['bin', 'sbin']:
+ dir = os.path.join(self.destdir, 'usr', dir)
+
+ brokenlinks = []
+ for root, fnames, dnames in os.walk(dir):
+ for fname in fnames:
+ fname = os.path.join(root, fname)
+ if os.path.islink(fname) and not os.path.lexists(fname):
+ brokenlinks.append(fname)
+
+ for link in brokenlinks:
+ target = os.readlink(link)
+
+ for dir in ['bin', 'sbin']:
+ newtarget = re.sub(r'^\.\./\.\./%s/\(.*\)' % dir, r'\.\./%s/\1' % dir, target)
+ if newtarget != target:
+ os.symlink(newtarget, link)
diff --git a/src/pylorax/scratch/utils.py b/src/pylorax/scratch/utils.py
new file mode 100644
index 00000000..93291678
--- /dev/null
+++ b/src/pylorax/scratch/utils.py
@@ -0,0 +1,161 @@
+import sys
+import os
+import commands
+import re
+import socket
+
+import logging
+logging.basicConfig(level=logging.DEBUG)
+logger = logging.getLogger('pylorax')
+
+
+def genmodinfo(path=None):
+ if not path:
+ release = os.uname()[2]
+ path = os.path.join('/lib/modules', release)
+
+ mods = {}
+ for root, dirs, files in os.walk(path):
+ for file in files:
+ mods[file] = os.path.join(root, file)
+
+ modules = { 'scsi_hostadapter': ['block'], 'eth': ['networking'] }
+ blacklist = ('floppy', 'scsi_mod', 'libiscsi')
+
+ list = {}
+ for modtype in modules:
+ list[modtype] = {}
+ for file in modules[modtype]:
+ try:
+ filename = os.path.join(path, 'modules.%s' % file)
+ f = open(filename, 'r')
+ except IOError:
+ logger.error('cannot open file %s', filename)
+ continue
+ else:
+ lines = f.readlines()
+ f.close()
+
+ for line in lines:
+ line = line.strip()
+ if line in mods:
+ modname, ext = os.path.splitext(line)
+ if modname in blacklist:
+ logger.info('skipping %s', modname)
+ continue
+
+ outtext = commands.getoutput('modinfo -F description %s' % mods[line])
+ desc = outtext.split('\n')[0]
+ desc = desc.strip()
+
+ # XXX why we need to do this?
+ desc = desc[:65]
+
+ if not desc:
+ desc = '%s driver' % modname
+ modinfo = '%s\n\t%s\n\t"%s"\n' % (modname, modtype, desc)
+ list[modtype][modname] = modinfo
+
+ # XXX i don't think we want to print it out now
+ print 'Version 0'
+ for type in list:
+ modlist = list[type].keys()
+ modlist.sort()
+ for m in modlist:
+ print list[type][m]
+
+
+# XXX is the input a path to a file?
+def filtermoddeps(input):
+ try:
+ f = open(input, 'r')
+ except IOError:
+ logger.error('cannot open file %s', input)
+ return
+
+ # concatenate lines ending with \
+ lines = []
+ for line in f.readlines():
+ if line.endswith('\\\n'):
+ line = line[:-2]
+ lines.append(line)
+
+ f.close()
+
+ lines = ''.join(lines).split('\n')
+
+ # XXX what's the purpose of these gentlemen?
+ lines = filter(lambda line: re.search(':.*ko', line), lines)
+ lines = map(lambda line: re.sub('\.ko', '', line), lines)
+ lines = map(lambda line: re.sub('/[^: ]*/', '', line), lines)
+ lines = map(lambda line: re.sub('\t+', ' ', line), lines)
+
+ return lines
+
+
+# XXX what are the inputs for this thing?
+def trimpciids(pciids, *paths):
+ vendors = []
+ devices = []
+
+ for file in paths:
+ try:
+ f = open(file, 'r')
+ except IOError:
+ logger.error('cannot open file %s', file)
+ continue
+ else:
+ pcitable = f.readlines()
+ f.close()
+
+ for line in pcitable:
+ if line.startswith('alias pci:'):
+ vend = '0x%s' % line[15:19]
+ dev = '0x%s' % line[24:28]
+ elif line.startswith('alias pcivideo:'):
+ vend = '0x%s' % line[20:24]
+ dev = '0x%s' % line[29:33]
+ else:
+ continue
+
+ vend = vend.upper()
+ dev = dev.upper()
+ if vend not in vendors:
+ vendors.append(vend)
+ if (vend, dev) not in devices:
+ devices.append((vend, dev))
+
+ current_vend = 0
+ for line in pciids:
+ if line.startswith('#') or line.startswith('\t\t') or line == '\n':
+ continue
+
+ # XXX print or return?
+ if not line.startswith('\t'):
+ current_vend = '0x%s' % line.split()[0]
+ current_vend = current_vend.upper()
+ if current_vend in vendors:
+ print line,
+ continue
+
+ # XXX print or return?
+ dev = '0x%s' % line.split()[0]
+ dev = dev.upper()
+ if (current_vend, dev) in devices:
+ print line,
+
+
+# XXX what is this whole thing for?
+def geninitrdsz(size, filename):
+ size = socket.htonl(size)
+
+ try:
+ f = open(filename, 'w')
+ except IOError:
+ logger.error('cannot open file %s', filename)
+ else:
+ f.write(str(size))
+ f.close()
+
+ # XXX is this needed? default mode is 0664
+ os.chmod(filename, 0644)
diff --git a/src/pylorax/treeinfo.py b/src/pylorax/treeinfo.py
deleted file mode 100644
index 92aa0e76..00000000
--- a/src/pylorax/treeinfo.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# pylorax treeinfo module
-# Install image and tree support data generation tool -- Python module.
-#
-# Copyright (C) 2007, 2008 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 .
-#
-# Author(s): David Cantrell
-# Will Woods
-#
-
-import os
-import time
-import ConfigParser
-
-# Write out the .treeinfo file
-def write(family=None, version=None, arch=None, outdir=None, variant='',
- discnum=None, totaldiscs=None, packagedir='', allDiscs=True):
- """write(family=None, version=None, arch=None, outdir=None,
- [variant='', discnum=None, totaldiscs=None, packagedir=''])
-
- Write the .treeinfo file to the specified directory (outdir).
-
- Required parameters:
- family String specifying the family.
- version String specifying the version number.
- arch String specifying the architecture.
- outdir Directory to write .treeinfo to (must exist).
-
- Optional parameters may be specified:
- variant Defaults to an empty string, but can be any string.
- discnum Defaults to '1', but you can specify an integer.
- totaldiscs Defaults to '1', but you can specify an integer.
- packagedir Directory where packages are located.
- allDiscs Boolean stating all discs are in one tree (default: True)
-
- Returns True on success, False on failure.
-
- """
-
- if family is None or arch is None or outdir is None:
- return False
-
- if not os.path.isdir(outdir):
- return False
-
- data = { "timestamp": float(time.time()),
- "family": family,
- "variant": variant,
- "version": version,
- "arch": arch,
- "discnum": "1",
- "totaldiscs": "1",
- "packagedir": packagedir,
- "outfile": None }
-
- outfile = "%s/.treeinfo" % (outdir,)
- section = 'general'
-
- c = ConfigParser.ConfigParser()
- c.add_section(section)
-
- if not allDiscs:
- if discnum is not None:
- data["discnum"] = str(discnum)
-
- if totaldiscs is not None:
- data["totaldiscs"] = str(totaldiscs)
-
- try:
- f = open(outfile, "w")
-
- for key, value in data.items():
- c.set(section, key, value)
-
- c.write(f)
- f.close()
- except:
- return False
-
- return True