#!/bin/bash ############################################################################## # run-anaconda # # Given a directory with the CD ISO images, run anaconda (or optionally # just a shell) in an environment like an install gets # # Copyright (c) 2004 # Chris Adams # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 as published by # the Free Software Foundation. # # 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Usage: # run-anconda [-s] [anaconda options] # -s: just open a shell instead of running anaconda # ISO path: path the the CD-ROM images # anaconda options: extra args to pass to anaconda # Some useful anaconda options: # --rootpath: path to an already mounted sysimage to install to # --method: how to install (pointed at ISO path by default) # --test: don't actually do the install, just go through the motions # # History: # 1.0 - 2004-06-05 # initial version # # Exit on any command error set -e if [ "$TMPDIR" = "" ]; then TMPDIR=/tmp fi if [ "$1" = "-s" ]; then # Get a root shell instead of running anaconda shell=1 shift else shell=0 fi if [ "$1" = "" ]; then echo "No image directory specified" 1>&2 exit 1 fi iso=$1 shift if [ ! -d $iso ]; then echo "Can't find image directory \"$iso\"" 1>&2 exit 1 fi cd=`/bin/ls -1 $iso/*disc1*iso | grep -v SRPMS` if [ ! -f "$cd" ]; then echo "Can't find CD #1 in image directory" 1>&2 exit 1 fi # Variables to keep track of what's going on root="" source="" TEMPS="" # Set up to unmount and clean up trap ' set +e if [ "$root" != "" ]; then while read dev mnt opt; do if [ $mnt = $source ]; then echo $mnt elif [ $mnt = $root ]; then echo $mnt elif [ ${mnt#$root/} != $mnt ]; then echo $mnt fi done < /proc/mounts |\ sort -r |\ while read mnt; do umount $mnt while grep -q " $mnt " /proc/mounts; do # Sleep and try again if the umount fails echo "Waiting for $mnt to be idle" 1>&2 sleep 1 umount $mnt done done fi rm -rf $TEMPS TEMPS="" ' 0 2 3 15 # Make the ISO path fully specified if [ "${iso#/}" = "$iso" ]; then iso=`cd $iso; pwd` fi # Mount the first CD source=`mktemp $TMPDIR/anacd.XXXXXXXX` TEMPS="$TEMPS $source" rm $source mkdir $source mount -o ro,loop=/dev/loop4 $cd $source # Get the root FS from the CD and mount it initrd=`mktemp $TMPDIR/initrd.XXXXXXXX` TEMPS="$TEMPS $initrd" gzip -dc < $source/isolinux/initrd.img > $initrd root=`mktemp $TMPDIR/anaroot.XXXXXXXX` TEMPS="$TEMPS $root" rm $root mkdir $root mount -o rw,loop=/dev/loop5 $initrd $root rm -f $initrd # Mount stage2 and proc mkdir -p $root/mnt/runtime mount -o ro,loop=/dev/loop6 $source/Fedora/base/stage2.img $root/mnt/runtime mount -t proc none $root/proc # Set up the source tree dev=`df -k $iso | tail -1 | awk '{print $1}'` point=`grep "^$dev " /proc/mounts | head -1 | awk '{print $2}'` dev=${dev#/dev/} src=${iso#$point/} if [ "$src" = "" ]; then echo "Can't find install source" 1>&2 exit 1 fi mkdir -p $root$iso mount --rbind $iso $root$iso # See if a root path was specified and bind mount it if so rpath=`echo $* | sed 's/.*--rootpath=\([^ ]*\).*/\1/'` if [ "$rpath" = "$*" ]; then rpath="" else echo "Mounting $rpath" 1>&2 mkdir -p $root$rpath mount --rbind $rpath $root$rpath fi # Make the symlinks for f in $root/mnt/runtime/*; do d=`basename $f` [ "$d" = "proc" ] && continue if [ -d $root/$d ]; then for f2 in $f/*; do d2=`basename "$f2"` if [ ! -e "$root/$d/$d2" ]; then ln -s "/mnt/runtime/$d/$d2" "$root/$d/$d2" fi done elif [ ! -e $root/$d ]; then ln -s /mnt/runtime/$d $root/$d fi done # Misc setup for f in /etc/hosts /etc/resolv.conf; do [ ! -e $root$f ] && cp $f $root$f done LD_LIBRARY_PATH=/usr/X11R6/lib export LD_LIBRARY_PATH # Copy any X authority data if [ "$DISPLAY" != "" ]; then disp="${DISPLAY#localhost}" if [ "$disp" != "$DISPLAY" ]; then disp="$DISPLAY $disp" fi xauth extract - $disp 2> /dev/null |\ xauth -f $root/.Xauthority merge - 2> /dev/null XAUTHORITY=/.Xauthority export XAUTHORITY case $DISPLAY in :*) DISPLAY=localhost$DISPLAY;; esac fi # See if a method was passed to override CD images method=`echo $* | sed 's/.*--method=\([^ ]*\).*/\1/'` if [ "$method" = "$*" ]; then method="--method=hd://$dev:/$src" else method="" fi # Chroot over and call the shell cmd="/usr/bin/anaconda $method $@" if [ $shell = 1 ]; then cmd="/usr/bin/bash -l" fi env -i \ LD_LIBRARY_PATH=$LD_LIBRARY_PATH \ DISPLAY=$DISPLAY \ XAUTHORITY=$XAUTHORITY \ HOME=/ \ TERM=xterm \ /usr/sbin/chroot $root $cmd