#
# Written by Richard W.M. Jones <rjones@redhat.com>
+unset CDPATH
+
TEMP=`getopt \
- -o g:i: \
- --long groupinstall:,group-install:,help,install: \
+ -o g:i:p:u: \
+ --long groupinstall:,group-install:,help,install:,noclean,no-clean,proxy:,updates: \
-n febootstrap -- "$@"`
if [ $? != 0 ]; then
echo "febootstrap: problem parsing the command line arguments"
packages[0]="@Core"
i=0
+clean=yes
+
usage ()
{
echo "Usage: febootstrap [--options] REPO TARGET [MIRROR]"
-i|--install)
packages[i++]="$2"
shift 2;;
- --groupinstall|--group-install)
+ -g|--groupinstall|--group-install)
packages[i++]="@$2"
shift 2;;
+ -p|--proxy)
+ proxy="proxy=$2"
+ shift 2;;
+ -u|--updates)
+ updates="$2";
+ shift 2;;
+ --noclean|--no-clean)
+ clean=no
+ shift;;
--help)
usage
exit 0;;
# Architecture is currently always the same as the current arch. We
# cannot do --foreign builds. See discussion in the manpage.
-arch=$(arch)
+arch=$(uname -m)
+case $arch in
+ i?86) arch=i386 ;;
+esac
# Create a temporary directory, make sure it gets cleaned up at the end.
tmpdir=$(mktemp -d)
failovermethod=priority
enabled=1
gpgcheck=0
+$proxy
__EOF__
# "Mirror" parameter is a bit misnamed, but it means a local mirror,
echo "mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=$repo&arch=$arch" >> "$tmpdir"/febootstrap.repo
fi
+# Add the updates repository if asked.
+case "$updates" in
+ ""|none|no)
+ ;;
+ *://*)
+ cat >> $tmpdir/febootstrap.repo <<EOF
+
+[febootstrap-updates]
+name=febootstrap updates $arch
+failovermethod=priority
+enabled=1
+gpgcheck=0
+$proxy
+baseurl=$updates
+EOF
+addrepo=febootstrap-updates
+ ;;
+ *)
+ cat >> $tmpdir/febootstrap.repo <<EOF
+
+[febootstrap-updates]
+name=febootstrap $updates $arch
+failovermethod=priority
+enabled=1
+gpgcheck=0
+$proxy
+mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=$updates&arch=$arch
+EOF
+addrepo=febootstrap-updates
+ ;;
+esac
+
# Create the target filesystem.
rm -rf "$target"
mkdir "$target"
+# Target must be an absolute path.
+target=$(cd "$target" > /dev/null; pwd)
+
# This is necessary to keep yum happy. It's not clear why yum can't
# just create this file itself.
mkdir -p "$target"/var/cache/yum/febootstrap/packages
-yumargs="-y --disablerepo=* --enablerepo=febootstrap --noplugins --nogpgcheck"
+# NB: REQUIRED for useradd/groupadd to run properly.
+#
+# However this causes 'filesystem' RPM install to give the
+# following error. Not sure how serious the error is:
+# error: unpacking of archive failed on file /proc: cpio: utime
+export FAKECHROOT_EXCLUDE_PATH=/proc
-# If we are root, then we don't need to run fakeroot and fakechroot.
-if [ $(id -u) -eq 0 ]; then
- yum \
- -c "$tmpdir"/febootstrap.repo \
- $yumargs \
- --installroot="$target" \
- install "${packages[@]}"
-else
+# Substitute some statically-linked commands. This is only supported
+# in fakechroot > 2.9. For previous versions of fakechroot it is
+# ignored.
+export FAKECHROOT_CMD_SUBST=/sbin/ldconfig=/bin/true:/usr/sbin/glibc_post_upgrade.i686=/bin/true:/usr/sbin/glibc_post_upgrade.x86_64=/bin/true:/usr/sbin/build-locale-archive=/bin/true:/usr/sbin/libgcc_post_upgrade=/bin/true:/sbin/new-kernel-pkg=/bin/true:/usr/sbin/nscd=/bin/true
+
+# Use the libraries inside the chroot.
+export LD_LIBRARY_PATH="$target"/usr/lib64:"$target"/usr/lib:"$target"/lib64:"$target"/usr/lib
+
+# Make the device nodes inside the fake chroot.
+# (Copied from mock/backend.py) Why isn't there a base package which
+# creates these?
+make_device_nodes ()
+{
+ mkdir "$target"/proc
+ mkdir "$target"/sys
+ mkdir "$target"/dev
+ (
+ cd "$target"/dev
+ mkdir pts
+ mkdir shm
+ mkdir mapper
+ mknod null c 1 3; chmod 0666 null
+ mknod full c 1 7; chmod 0666 full
+ mknod zero c 1 5; chmod 0666 zero
+ mknod random c 1 8; chmod 0666 random
+ mknod urandom c 1 9; chmod 0444 urandom
+ mknod tty c 5 0; chmod 0666 tty
+ mknod console c 5 1; chmod 0600 console
+ mknod ptmx c 5 2; chmod 0666 ptmx
+ ln -sf /proc/self/fd/0 stdin
+ ln -sf /proc/self/fd/1 stdout
+ ln -sf /proc/self/fd/2 stderr
+ )
+}
+export -f make_device_nodes
+export target
+
+if [ $(id -u) -ne 0 ]; then
fakeroot -s "$target"/fakeroot.log \
- fakechroot -s \
+ make_device_nodes
+else
+ make_device_nodes
+fi
+
+repos=febootstrap
+if [ -n "$addrepo" ]; then
+ repos="$repos,$addrepo"
+fi
+
+# Run yum.
+run_yum ()
+{
yum \
- -c "$tmpdir"/febootstrap.repo \
- $yumargs \
+ -y -c "$tmpdir"/febootstrap.repo \
+ --disablerepo=* --enablerepo=$repos \
+ --noplugins --nogpgcheck \
--installroot="$target" \
- install "${packages[@]}"
+ install "$@"
+}
+export -f run_yum
+export tmpdir
+export repos
+
+if [ $(id -u) -ne 0 ]; then
+ # Bash doesn't support exporting array variables, hence this
+ # tortuous workaround.
+ fakeroot -i "$target"/fakeroot.log -s "$target"/fakeroot.log \
+ fakechroot -s \
+ bash -c 'run_yum "$@"' run_yum "${packages[@]}"
+else
+ run_yum "${packages[@]}"
+fi
+
+# Clean up the yum repository.
+if [ "$clean" = "yes" ]; then
+ febootstrap-run "$target" -- rm -rf /var/cache/yum/febootstrap
+ febootstrap-run "$target" -- rm -rf /var/cache/yum/febootstrap-updates
fi