#!/bin/bash
#
# upd-instroot
#
# 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 .
#
ORIGDIR=`pwd`
DEBUG=""
NEEDGR=yes
if [ "$1" == "--debug" ]; then
DEBUG="--debug"
shift
fi
if [ "$1" == "--nogr" ]; then
NEEDGR=""
shift
fi
if [ -z "$1" ]; then
echo "upd-instroot: updates instimage from a Red Hat RPMS directory"
echo "usage: $0 [templatedir] [instroot]"
exit 1
fi
if [ ! -d $1 ]; then
if [ -z "$ARCH" ]; then
echo "ARCH must be set" >&2
exit 1
fi
fi
PACKAGEDIR=$1
if [ -z "$ARCH" ]; then
ARCH=`rpm --nodigest --nosignature -qp --qf "%{ARCH}" $PACKAGEDIR/anaconda-runtime*.rpm`
fi
if [ $ARCH = x86_64 -o $ARCH = s390x -o $ARCH = ppc64 ]; then
LIBDIR=lib64
else
LIBDIR=lib
fi
. $(dirname $0)/buildinstall.functions
expandPackageSet() {
YUMCONF=$1
YUMDIR=$2
RPMS=$3
PKGDEST=$4
KEEPFILES=$5
[ -d $PKGDEST ] || die "ERROR: directory missing: $PKGDEST"
yum -c $YUMCONF -y --installroot=$YUMDIR install $RPMS 2>&1 || die "ERROR: could not install packages"
# figure out the theme to keep
if [ -f $YUMDIR/etc/gtk-2.0/gtkrc ]; then
gtktheme=$(grep "gtk-theme-name" $YUMDIR/etc/gtk-2.0/gtkrc | awk {'print $3;'} | sed -e 's/"//g')
echo "usr/share/themes/$gtktheme" >> $KEEPFILES
# find gtk engine needed
for engine in `grep engine $YUMDIR/usr/share/themes/$gtktheme/gtk-2.0/gtkrc | awk {'print $2;'} | sed -e 's/"//g' | sort -u` ; do
echo "usr/$LIBDIR/gtk-2.0/*/engines/*$engine*" >> $KEEPFILES
done
theme=$(grep "gtk-icon-theme-name" $YUMDIR/etc/gtk-2.0/gtkrc | awk {'print $3;'} | sed -e 's/"//g')
while [ -n "$theme" ]; do
echo "usr/share/icons/$theme" >> $KEEPFILES
theme=$(grep Inherits $YUMDIR/usr/share/icons/$theme/index.theme | cut -d = -f 2)
done
fi
echo `date` "Installing files"
pushd $YUMDIR >/dev/null
cat $KEEPFILES | while read spec ; do
#Pull off path
path=`echo "$spec" | sed 's,\([^[*\?]*\)/.*,\1,'`
for filespec in `find ./$path -path "./$spec"` ; do
if [ ! -e $filespec ]; then
continue
elif [ ! -d $filespec ]; then
instFile $filespec $PKGDEST
else
for i in `find $filespec -type f` ; do instFile $i $PKGDEST ; done
for i in `find $filespec -type l` ; do instFile $i $PKGDEST ; done
for d in `find $filespec -type d` ; do instDir $d $PKGDEST ; done
fi
done
done
popd >/dev/null
}
die () {
echo "$@"
echo "Aborting instroot creation..."
exit 1
}
if [ -z "$2" ]; then
DEST=${TMPDIR:-/tmp}/upd-instroot
else
DEST=$2
fi
if [ -z "$3" ]; then
DESTGR=${TMPDIR:-/tmp}/upd-instroot
else
DESTGR=$3
fi
if [ -n "$4" ]; then
TOPDIR=$4
elif [ -d $PACKAGEDIR/repodata ]; then
TOPDIR=$PACKAGEDIR
elif [ -d $PACKAGEDIR/../repodata ]; then
TOPDIR=$PACKAGEDIR/..
elif [ -d $PACKAGEDIR/../../repodata ]; then
TOPDIR=$PACKAGEDIR/../..
else
echo "Unable to find repodata!"
exit 1
fi
rm -rf $DEST $DESTGR
mkdir -p $DEST
mkdir -p $DESTGR
PACKAGES="glibc-common setup python newt slang libselinux
libsepol libtermcap zlib ash e2fsprogs util-linux raidtools popt
procps rpm rpm-libs Xconfigurator anaconda tzdata python-libs
anaconda-runtime kudzu hwdata bzip2 beecrypt mdadm libsemanage
bzip2-libs dosfstools pciutils reiserfs-utils parted sed
busybox-anaconda rpm-python booty hdparm lvm2 beecrypt
rhpl pyxf86config libxml2 glib2 sqlite neon libselinux-python
elfutils-libelf krb5-libs convertdb1 jfsutils audit-libs pam
xfsprogs xfsdump dmapi libacl libattr attr acl python-urlgrabber
policy policycoreutils pyparted xorg-x11 selinux-policy-targeted
libstdc++ expat libgcc readline ncurses yum python-sqlite
python-elementtree pykickstart e2fsprogs-libs iscsi-initiator-utils
db4 rhpxl xorg-x11-server-Xorg libuser-python libuser system-config-date
yum-metadata-parser gfs2-utils libvolume_id nash yum-fedorakmod
libdhcp libnl libdhcp6client libdhcp4client newt-python
device-mapper device-mapper-libs dmraid keyutils-libs libsemanage-python
python-pyblock mkinitrd libbdevid libbdevid-python nss nspr pcre
cryptsetup-luks libgcrypt libgpg-error dbus dbus-python hal
cracklib-python module-init-tools cracklib-dicts"
if [ $ARCH = i386 ]; then
PACKAGES="$PACKAGES glibc.i386 openssl.i386"
else
PACKAGES="$PACKAGES glibc openssl"
fi
if [ $ARCH = i386 -o $ARCH = x86_64 ]; then
PACKAGES="$PACKAGES pcmciautils"
fi
if [ $ARCH = i386 -o $ARCH = x86_64 -o $ARCH = ia64 ]; then
PACKAGES="$PACKAGES dmidecode"
fi
if [ $ARCH = ia64 ]; then
PACKAGES="$PACKAGES elilo"
fi
if [ $ARCH = s390 -o $ARCH = s390x ]; then
PACKAGES="$PACKAGES s390utils binutils libgcc tcp_wrappers
sed net-tools openssh openssh-server coreutils
login initscripts bash portmap pam
login mount grep modutils gawk
strace xorg-x11-xauth xorg-x11-libs"
fi
if [ $ARCH = ppc -o $ARCH = ppc64 ]; then
PACKAGES="$PACKAGES pcmciautils pdisk yaboot hfsutils"
fi
# xpm is missing
# Some packages are listed twice, but that's okay
#
# The packages in this list are needed for the graphical installer to run
#
# Extra stuff we want for rescue mode should go in PACKAGESRESCUE
#
PACKAGESGR="anaconda libpng gtk2 libglade2 fonts-ISO8859-2 fonts-ISO8859-9
e2fsprogs coreutils glibc-common
popt specspo util-linux rpm rpm-libs tzdata
procps bash cpio gpm pygtk2-libglade pygobject2
Xconfigurator pygtk2 gdk-pixbuf libpixman
reiserfs-utils atk pango freetype gnome-python2-canvas cairo
libgnomecanvas libart_lgpl libgcc libacl libattr libstdc++ expat
anaconda-images anaconda-help ttfonts-ko taipeifonts rhpl
system-config-keyboard Xft fontconfig gtk2-engines gnome-themes
gtkhtml2 gnome-python2-gtkhtml2 gail libthai
ttfonts-ja ttfonts-zh_TW bitmap-fonts-cjk urw-fonts fonts-arabic
comps-extras convertdb1 fonts-bengali
vnc-server vnc-libs libjpeg tcp_wrappers system-config-date
xfsprogs xfsdump dmapi attr acl policy policycoreutils
selinux-policy-targeted ttfonts-zh_CN redhat-artwork
xorg-x11-libs xorg-x11-ISO8859-2-75dpi-fonts echo-icon-theme
xorg-x11-ISO8859-9-75dpi-fonts xorg-x11-100dpi-fonts
xorg-x11-xfs xorg-x11 xorg-x11-KOI8-R xorg-x11-KOI8-R-75dpi-fonts
xorg-x11-base-fonts xorg-x11-ISO8859-15-75dpi-fonts
fonts-xorg-ISO8859-2-75dpi fonts-xorg-ISO8859-15-75dpi
fonts-xorg-ISO8859-9-75dpi fonts-xorg-100dpi
fonts-xorg-KOI8-R fonts-xorg-KOI8-R-75dpi fonts-xorg-base
xorg-x11-base xorg-x11-ISO8859-15-75dpi system-logos
xorg-x11-libs-data xorg-x11-xfs prelink redhat-logos fedora-logos
ttfonts-ta ttfonts-bn ttfonts-gu ttfonts-hi ttfonts-pa
fonts-japanese fonts-chinese fonts-korean fonts-indic fonts-sinhala
fonts-malayalam fonts-oriya fonts-kannada fonts-telugu cjkunifonts-ukai
fonts-gujarati fonts-hindi fonts-punjabi fonts-tamil synaptics
firstboot pycairo pirut dejavu-fonts libxcb VLGothic-fonts
dmraid python-pyblock libbdevid libbdevid-python zenity udev dbus dbus-python hal"
#
# stuff ONLY included for rescue mode
#
# these packages are combined with the PACKAGES and PACKAGESGR for big stage 2
#
PACKAGESRESCUE="bzip2 bzip2-libs dump libidn groff
findutils ftp gzip iputils joe krb5-libs less man
modutils mtools mt-st mtr net-tools open smartmontools
openssh openssh-clients pciutils rsh traceroute tar rsync
device-mapper device-mapper-libs dmraid ntfsprogs samba-client
firstaidkit-plugin-all"
if [ $ARCH = i386 -o $ARCH = x86_64 ]; then
PACKAGESRESCUE="$PACKAGESRESCUE gpart grub"
fi
# turn off options we dont want, ie. set package list to something harmless
if [ -z "$NEEDGR" ]; then
PACKAGESGR="bash"
PACKAGESRESCUE="bash"
fi
#
# add bootloader for particular arch
#
if [ $ARCH = sparc ]; then
PACKAGESGR="$PACKAGESGR tilo silo"
fi
if [ $ARCH = i386 -o $ARCH = x86_64 ]; then
PACKAGESGR="$PACKAGESGR syslinux memtest86+"
fi
if [ $ARCH = alpha ]; then
PACKAGESGR="$PACKAGESGR aboot"
fi
if [ $ARCH = ia64 ]; then
PACKAGESGR="$PACKAGESGR elilo"
fi
if [ $ARCH = ppc ]; then
PACKAGESGR="$PACKAGESGR fbset yaboot ppc64-utils"
fi
# dogtail stuff...
PACKAGESGR="$PACKAGESGR gail at-spi libbonobo ORBit2"
# modular xorg...
XORGLIBS="libICE libSM libX11 libXcursor libXext libXfixes libXft libXi libxkbfile libXmu libXpm libXrandr libXrender libXt libXxf86misc libXaw liblbxutil libXfont libfontenc libXau libXdmcp libXfont libXinerama"
XORGFONTS="xorg-x11-fonts-75dpi xorg-x11-fonts-base xorg-x11-fonts-cyrillic xorg-x11-fonts-ISO8859-15-75dpi xorg-x11-fonts-ISO8859-1-75dpi xorg-x11-fonts-ISO8859-2-75dpi xorg-x11-fonts-ISO8859-9-75dpi xorg-x11-fonts-misc xorg-x11-fonts-ethiopic"
XORG="$XORGLIBS xorg-x11-drivers $XORGFONTS xorg-x11-server-Xorg xorg-x11-xauth xorg-x11-font-utils xorg-x11-xkb-utils xorg-x11-xkbdata xorg-x11-server-utils xkeyboard-config"
PACKAGES="$PACKAGES $XORGDRIVERS"
PACKAGESGR="$PACKAGESGR $XORG"
#
# KEEPFILE is all files to keep from the packages in PACKAGES
#
# This is what is present in http, ftp, and hard drive installs, and is
# supposed to be a small image because these methods keep it in RAM.
#
# It also is the base on which the other install images build on top of,
# so if something is needed by all images it should go here
#
KEEPFILE=${TMPDIR:-/tmp}/keepfile.$$
cat > $KEEPFILE <> $KEEPFILE <> $KEEPFILEGR <> $KEEPFILEGR < $KEEPFILERESCUE <> $KEEPFILERESCUE <<-EOF
boot/grub
sbin/grub
sbin/grub-install
sbin/grub-md5-crypt
sbin/grub-set-default
usr/bin/gpart
usr/bin/mbchk
usr/share/grub
EOF
fi
echo "Assembling package list..."
RPMS="$PACKAGES"
[ -n "$DEBUG" ] && echo "RPMS are $RPMS"
RPMSGR="$PACKAGES $PACKAGESGR $PACKAGESRESCUE"
[ -n "$DEBUG" ] && echo "RPMSGR are $RPMSGR"
rm -rf $DEST; mkdir -p $DEST/usr/sbin
rm -rf $DESTGR; mkdir -p $DESTGR/usr/sbin $DESTGR/var/lib $DESTGR/boot
ln -s /tmp $DESTGR/var/lib/xkb
#
# concat KEEPFILEGR and KEEPFILERESCUE lists
#
cat $KEEPFILERESCUE >> $KEEPFILEGR
cat $KEEPFILE >> $KEEPFILEGR
yumconf=$(mktemp /tmp/yum.conf.XXXXXX)
cat > $yumconf < 1) {
print gensub(/\..*$/,tolower("." a[2]),"",$4);
};
print $2;
}
' | sed -e 's/latn/Latn/g' | LC_ALL=C sort -u > $DESTGR/locales
for p in lib share; do (
cd $DESTGR/usr/$p/locale && {
ls | grep -v locale.alias | grep -v locale-archive | LC_ALL=C sort > $DESTGR/locales.list
LC_ALL=C comm -13 $DESTGR/locales $DESTGR/locales.list | xargs rm -rf
}
); done
rm -f $DESTGR/locales $DESTGR/locales.list
# fixup joe links
if [ -n "$NEEDGR" -a -d "$DESTDIR"/etc/joe ]; then
ln -fs jpicorc $DESTGR/etc/joe/picorc
ln -fs jpicorc $DESTGR/etc/joe/jnanorc
ln -fs jpicorc $DESTGR/etc/joe/nanorc
ln -fs jmacsrc $DESTGR/etc/joe/emacsrc
ln -fs jmacs $DESTGR/usr/bin/emacs
ln -fs jpico $DESTGR/usr/bin/pico
ln -fs jpico $DESTGR/usr/bin/nano
fi
# create selinux config
if [ -e $DEST/etc/selinux/targeted ]; then
cat > $DEST/etc/selinux/config < $DEST/etc/shells < $DEST/etc/nsswitch.conf < $DEST/etc/libuser.conf < $DESTGR/etc/man.config
rm -f $DESTGR/etc/man.config-old
fi
if [ -n "$NEEDGR" ]; then
echo "Running mkfontdir..."
mkfontdir $DESTGR/usr/share/X11/fonts/*
fi
echo "Creating SELinux policy..."
if [ -x $DESTGR/usr/sbin/semodule ]; then
( cd $DESTGR
x=$(ls usr/share/selinux/targeted/*.pp | grep -v -e base.pp -e enableaudit.pp | awk '{ print "-i /" $1 }')
/usr/sbin/chroot $DESTGR /usr/sbin/semodule -b /usr/share/selinux/targeted/base.pp $x -n -s targeted )
fi
rm -rf $DEST/etc/selinux
rm -rf $DEST/usr/share/selinux $DESTGR/usr/share/selinux
mkdir $DEST/etc/selinux
cp -r $DESTGR/etc/selinux/* $DEST/etc/selinux/
rm -f $KEEPFILE $KEEPFILEGR $KEEPFILERESCUE
for p in $DEST $DESTGR; do
echo "Scrubbing trees..." "$p"
mkdir -p $p/lib
mkdir -p $p/firmware
ln -snf /modules $p/lib/modules
ln -snf /firmware $p/lib/firmware
cp $p/usr/lib/anaconda/raidstart-stub $p/usr/bin/raidstart
cp $p/usr/lib/anaconda/raidstop-stub $p/usr/bin/raidstop
cp $p/usr/lib/anaconda/losetup-stub $p/usr/bin/losetup
cp $p/usr/lib/anaconda/dhcpclient-stub $p/usr/bin/dhcpclient
( cd $p/usr/bin && rm -f pump && ln -sf dhcpclient pump )
cp $p/usr/lib/anaconda/list-harddrives-stub $p/usr/bin/list-harddrives
cp $p/usr/lib/anaconda/kudzu-probe-stub $p/usr/bin/kudzu-probe
cp $p/usr/lib/anaconda/loadkeys-stub $p/usr/bin/loadkeys
cp $p/usr/lib/anaconda/mknod-stub $p/usr/bin/mknod
cp $p/usr/lib/anaconda/syslogd-stub $p/usr/bin/syslogd
mv $p/usr/sbin/anaconda $p/usr/bin/anaconda
mv $p/usr/lib/anaconda-runtime/lib* $p/usr/$LIBDIR
# we only want the libunicode-lite stuff on the minimal image
if [ $p = $DESTGR ]; then
rm -f $p/usr/$LIBDIR/libunicode-lite*
fi
find $p -type d | xargs chmod 755
if [ -f $p/bin/bash ]; then
rm -f $p/bin/ash
ln -s bash $p/bin/sh
else
ln -sf busybox $p/bin/sh
fi
[ -d $p/bin ] || die "ERROR: directory missing: $p/bin"
[ -d $p/sbin ] || die "ERROR: directory missing: $p/sbin"
(cd $p/bin; find) | (cd $p/bin; /bin/cpio --quiet -pdmu $p/usr/bin)
(cd $p/sbin; find) | (cd $p/sbin; /bin/cpio --quiet -pdmu $p/usr/sbin)
rm -rf $p/bin
rm -rf $p/sbin
# copy bootloader files for sparc
if [ $ARCH = sparc -a $p = $DESTGR ]; then
mkdir -p $p/usr/lib/anaconda-runtime/boot
[ -d $p/boot ] || die "ERROR: directory missing: $p/boot"
(cd $p/boot; find -name "*.b") | (cd $p/boot; /bin/cpio --quiet -pdmu $p/usr/lib/anaconda-runtime/boot)
fi
# copy bootloader file for ppc
if [ $ARCH = ppc -o $ARCH = ppc64 ]; then
mkdir -p $p/usr/lib/anaconda-runtime/boot
cp -af $p/boot/efika.forth $p/usr/lib/anaconda-runtime/boot
fi
# copy bootloader file for alpha
if [ $ARCH = alpha -a $p = $DESTGR ]; then
mkdir -p $p/usr/lib/anaconda-runtime/boot
cp -af $p/boot/bootlx $p/usr/lib/anaconda-runtime/boot
fi
# copy bootloader files for ia64
if [ $ARCH = ia64 -a $p = $DESTGR ]; then
mkdir -p $p/usr/lib/anaconda-runtime/boot
cp -af $p/boot/efi/EFI/redhat//* $p/usr/lib/anaconda-runtime/boot
fi
# copy bootloader files for i386/x86_64
if [ $ARCH = i386 -o $ARCH = x86_64 ]; then
if [ $p = $DESTGR ]; then
mkdir -p $p/usr/lib/anaconda-runtime/boot
cp -af $p/boot/memtest* $p/usr/lib/anaconda-runtime/boot
fi
fi
rm -rf $p/boot $p/home $p/root $p/tmp
find $p -name "*.a" | grep -v kernel-wrapper/wrapper.a | xargs rm -rf
find $p -name "lib*.la" |grep -v "usr/$LIBDIR/gtk-2.0" | xargs rm -rf
for f in newt popt rpm rpmio; do
rm -f $p/usr/$LIBDIR/lib$f.so
done
# 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 $p/$d
done
if [ "$ARCH" != "s390" -a "$ARCH" != "s390x" ]; then
(cd $p/lib* && rm -f libnss_files.so.1 libnss_dns.so.1)
fi
if [ -d $DEST/usr/share/zoneinfo ]; then
(cd $DEST/usr/share/zoneinfo; find . -type f -or -type l |
grep '^./[A-Z]' | sort | sed 's/^..//' |
gzip -9) > $p/usr/lib/timezones.gz
else
echo "ERROR: unable to explode tzdata for small images"
fi
$p/usr/lib/anaconda-runtime/scrubtree $p
done
echo "Compressing .mo files in stage2 images..."
if [ -d $DEST/usr/share/locale ]; then
for i in `find $DEST/usr/share/locale -name anaconda.mo`; do
gzip -9 $i
mv -f $i.gz $i
done
fi
if [ -n "$NEEDGR" ]; then
echo "Creating fontconfig cache"
/usr/sbin/chroot $DESTGR /usr/bin/fc-cache
rm -f $DESTGR/usr/bin/fc-cache
fi
echo "Creating debug dir"
for p in $DEST $DESTGR ; do
mkdir -p $p/usr/lib/debug
mkdir -p $p/usr/src/debug
done
if [ $ARCH = "alpha" ]; then
rm -rf $DEST/usr/share/locale
rm -rf $DEST/usr/$LIBDIR/locale
fi
echo "Patching python library..."
# always use passive mode for ftp installs
cd $DEST/usr/$LIBDIR/python*
patch -p0 > /dev/null <