Rev 139 | Blame | Last modification | View Log | Download | RSS feed
#!/bin/bash
#
###############################################################
#
# Installes the LiveCD on local hard disk
#
# Boot LiveCD and run this script as root
#
# Urs Beyerle, PSI
#
###############################################################
###############################################################
# Definitions
###############################################################
# set PATH
PATH="/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin"
# RPMs that are no longer needed and may break future udpates
RPMS_TO_REMOVE="kernel-module-squashfs \
kernel-module-unionfs \
kernel-module-aufs \
unionfs-.* \
aufs-.* \
squashfs-.*"
# RPMs that can break future Scientific Linux updates
# because there are not part of Scientific Linux
RPMS_TO_REMOVE_SL=""
# RPMs that can break future PSI SL updates
# because there are not part of PSI Scientific Linux
RPMS_TO_REMOVE_PSI=""
# files which should be restored from .ori files
FILES_RESTORE="/etc/init.d/netfs \
/etc/init.d/autofs \
/etc/init.d/halt \
/etc/init.d/network
/etc/init.d/functions \
/etc/rc.d/rc.sysinit \
/etc/sysconfig/afs \
/etc/motd \
/etc/redhat-release \
/etc/rc.d/rc.local"
# LiveCD init scripts will be removed
LIVECD_INIT_SCRIPTS="runfirst \
runveryfirst \
runlast \
kudzu-auto \
login"
# Main directories which should be not be copied
DIR_NOT_COPY="/proc \
/dev \
/livecd \
/boot \
/afs \
/sys \
/media \
/misc \
/mnt \
/net \
/initrd"
# Mount point of the new SL system
NEW=/mnt/harddisk
# Name of the script
SCRIPTNAME=$( basename $0 )
# dir of mounted /$MOUNTDIR/live
MOUNTDIR=livecd
###############################################################
# Functions
###############################################################
function usage() {
## Usage
# ----------------------------------------------------------
cat <<EOF
$SCRIPTNAME [OPTIONS] -mbr=[DEVICE] [PARTITION]
Installes LiveCD on PARTITION and the bootloader grub into
the Master Boot Record (MBR) of DEVICE. The MBR will be
backed up to PARTITION.
OPTIONS:
-h --help : Print this screen
-swap=[partition] : Use [partition] as swap
-win=[partition] : Your active Windows partition. If not given,
$SCRIPTNAME tries to find it
-nogrub : Do not install grub. You have to install
manually a bootloader (not recommended)
-floppy : Needed, if grub should be installed on floppy
In this case use -mbr=/dev/fd0 -floppy
-norpmremove : Do not remove RPMs that can break future
updates (not recommended)
-y : Answer all questions with yes
Example:
$SCRIPTNAME -swap=/dev/sda3 -mbr=/dev/sda /dev/sda2
Will install LiveCD on /dev/sda2 (= second partition on
first SATA disk). All data on /dev/sda2 will be deleted.
/dev/sda3 has to be a Linux Swap partion. GRUB will be
installed in the MBR of /dev/sda (= first SATA disk).
Remarks:
To display your hard disk partitions, user 'fdisk -l'.
Use fdisk, qtparted or parted to create an empty Linux
partition.
EOF
}
function exit_now() {
local exitcode=$1
umount $INSTALL_PART 2>/dev/null
exit $exitcode
}
###############################################################
# Main
###############################################################
### are we root?
### -----------------------------------------------------------
if [ "$( whoami )" != "root" ]; then
echo; echo "Please run this script as root: 'su - -c $SCRIPTNAME'"; echo
exit_now 1
fi
### read options from command-line
### -----------------------------------------------------------
while [ $# -gt 0 ]; do
case "$1" in
-h)
usage; exit_now;;
--help)
usage; exit_now;;
-swap*)
if echo $1 | grep -q '=' ; then
SWAP_PART=$( echo $1 | sed 's/^-swap=//' )
else
shift
SWAP_PART=$1
fi
;;
-mbr*)
if echo $1 | grep -q '=' ; then
MBR_DEV=$( echo $1 | sed 's/^-mbr=//' )
else
shift
MBR_DEV=$1
fi
;;
-win*)
if echo $1 | grep -q '=' ; then
WIN_PART=$( echo $1 | sed 's/^-win=//' )
else
shift
WIN_PART=$1
fi
;;
-nogrub)
NOGRUB=$1;;
-norpmremove)
NORPMREMOVE=$1;;
-floppy)
FLOPPY=$1;;
-y)
YES=$1;;
*)
INSTALL_PART=$1;;
esac
shift
done
echo
### display fdisk -l
### -----------------------------------------------------------
echo "Output of 'fdisk -l' ..."
fdisk -l
echo
### test if $INSTALL_PART is defined
### -----------------------------------------------------------
if [ ! $INSTALL_PART ]; then
echo "No partition defined for installation."
echo "Please see '$SCRIPTNAME -h'."; echo
exit_now 1
fi
### test if MBR_DEV is given
### -----------------------------------------------------------
if [ ! $NOGRUB ]; then
if [ ! $MBR_DEV ]; then
echo "No MBR device defined."
echo "Please see '$SCRIPTNAME -h'."
echo
exit_now 1
fi
fi
### test if $INSTALL_PART exists
### -----------------------------------------------------------
fdisk -l | cut -d" " -f1 | grep -q "^${INSTALL_PART}$"
if [ "$?" != "0" ]; then
echo "Partition $INSTALL_PART not found! See 'fdisk -l'."
echo "Or you have to reboot first to make the partition table active."
echo
exit_now 1
fi
### test if $INSTALL_PART is a Linux partition
### -----------------------------------------------------------
fdisk -l | grep "Linux$" | cut -d" " -f1 | grep -q "^${INSTALL_PART}$"
if [ "$?" != "0" ]; then
echo "Partition $INSTALL_PART is not a Linux partition! (see 'fdisk -l')."
echo "Use fdisk and/or qtparted to create a Linux partition!"
echo "You have to reboot first to make the partition table active."
echo
exit_now 1
fi
### test if $SWAP_PART exists and is a Linux Swap partition
### -----------------------------------------------------------
if [ $SWAP_PART ]; then
fdisk -l | cut -d" " -f1 | grep -q "^${SWAP_PART}$"
if [ "$?" != "0" ]; then
echo "Swap partition $SWAP_PART not found! (see 'fdisk -l')."
echo "Or you have to reboot first to make the partition table active."
echo
exit_now 1
fi
fdisk -l | grep "Linux swap" | cut -d" " -f1 | grep -q "^${SWAP_PART}$"
if [ "$?" != "0" ]; then
echo "Partition $SWAP_PART is not a Linux swap partition! (see 'fdisk -l')."
echo "Use fdisk and/or qtparted to create a Linux Swap partition !"
echo "You have to reboot first to make the partition table active."
echo
exit_now 1
fi
fi
### set $INSTALL_DEV (eg. /dev/sda)
### -----------------------------------------------------------
INSTALL_DEV=$( echo "$INSTALL_PART" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' )
INSTALL_PART_NR=$( echo "$INSTALL_PART" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' )
### print warning
### -----------------------------------------------------------
echo "------------------------------------------------------------"
echo " LiveCD will be installed on partition $INSTALL_PART"
[ "$SWAP_PART" ] && echo " Partition $SWAP_PART will be used as swap partition."
[ ! $NOGRUB ] && echo " GRUB will be installed in Master Boot Record of $MBR_DEV"
echo " !! All data on $INSTALL_PART will be lost !!"
echo "------------------------------------------------------------"
echo
### continue?
### -----------------------------------------------------------
if [ ! $YES ]; then
echo -n "Continue (y/N)? "
read key
echo
[ "$key" != "y" ] && exit_now 0
fi
### format $SWAP_PART (don't format swap, if already formated)
### -----------------------------------------------------------
if [ $SWAP_PART ]; then
echo "Make swap on $SWAP_PART ..."
swapoff -a >/dev/null 2>&1
swapon $SWAP_PART 2>/dev/null
if [ "$?" != "0" ]; then
echo "Format $SWAP_PART as swap."
mkswap $SWAP_PART
fi
echo
fi
### format $INSTALL_PART
### -----------------------------------------------------------
echo -n "Format $INSTALL_PART, please wait ... "
mkfs.ext3 -q $INSTALL_PART || exit_now 1
echo "done."; echo
### mount $INSTALL_PART
### -----------------------------------------------------------
echo -n "Try to mount $INSTALL_PART to $NEW ... "
mkdir -p $NEW
mount $INSTALL_PART $NEW || exit_now 1
echo "done."; echo
### copy root dirs
### -----------------------------------------------------------
echo "Copy Live System to $INSTALL_PART ..."
root_dirs=$( ls / )
for dir in $root_dirs; do
# check if dir is not in $DIR_NOT_COPY
do_not_copy=""
for not_dir in $DIR_NOT_COPY; do
if [ "$not_dir" = "/$dir" ]; then
do_not_copy="yes"
break
fi
done
# do not copy links
[ -L /$dir ] && do_not_copy="yes"
fail=""
if [ ! $do_not_copy ]; then
echo -n " * Copy /$dir ... "
cp -a /$dir $NEW || fail=true
echo "done."
fi
done
echo
if [ $fail ]; then
echo "ERROR: Not everything was copied to $INSTALL_PART"
exit_now 1
fi
### move /usr/opt back to /opt
### -----------------------------------------------------------
if [ -d $NEW/usr/opt ]; then
echo -n "Move /opt back ... "
mv $NEW/usr/opt $NEW/
echo "done."; echo
fi
### create dirs which were not copied
### -----------------------------------------------------------
for dir in $DIR_NOT_COPY; do
mkdir $NEW/$dir
done
# we do not need this directories
rmdir $NEW/livecd
# if not yet existing, create
mkdir -p $NEW/srv
mkdir -p $NEW/selinux
### copy back original files
### -----------------------------------------------------------
echo -n "Restore original files ... "
for file in $FILES_RESTORE; do
[ -r $NEW/${file}.ori ] && mv -f $NEW/${file}.ori $NEW/${file}
done
echo "done."; echo
### define kernel version
### -----------------------------------------------------------
rpm --quiet -q kernel && UP_installed=true
rpm --quiet -q kernel-smp && SMP_installed=true
[ $UP_installed ] && KERNEL_VERSION=$( rpm -q --qf "%{V}-%{R}" kernel 2>/dev/null )
[ $SMP_installed ] && KERNEL_VERSION=$( rpm -q --qf "%{V}-%{R}" kernel-smp 2>/dev/null )
if [ ! $KERNEL_VERSION ]; then
echo "ERROR: Kernel version could not be determined - installation failed"; echo
exit_now 1
fi
if [ ! $NOGRUB ]; then
### Backup Master Boot Record MBR
### -----------------------------------------------------------
if [ ! $NOGRUB ]; then
# do we have already a backup?
MBR_FILENAME="MBR$( echo $MBR_DEV | tr / _ ).bak"
if [ ! -e /tmp/$MBR_FILENAME ]; then
echo "Backup Master Boot Record (MBR) of $MBR_DEV ..."
dd if=$MBR_DEV of=/tmp/$MBR_FILENAME bs=512 count=1
fi
cp -a /tmp/$MBR_FILENAME $NEW/$MBR_FILENAME
echo "MBR saved as $MBR_FILENAME on $INSTALL_PART and on /tmp"
echo
fi
### install grub
### -----------------------------------------------------------
echo "Run grub-install ... "
mkdir -p $NEW/boot/grub
if [ $FLOPPY ]; then
grub-install --root-directory=$NEW $MBR_DEV
else
grub-install --no-floppy --root-directory=$NEW $MBR_DEV
fi
echo "done."; echo
### check for device.map file
### -----------------------------------------------------------
DEVICE_MAP=$NEW/boot/grub/device.map
if [ ! -e $NEW/boot/grub/device.map ]; then
echo "ERROR: $NEW/boot/grub/device.map not found"
exit_now 1
fi
### convert dev syntax to grub syntax
### -----------------------------------------------------------
GRUB_INSTALL_DEV=$( grep $INSTALL_DEV $DEVICE_MAP | awk '{ print $1 }' )
GRUB_ROOT_PART=$( echo "$GRUB_INSTALL_DEV" | sed "s%)$%,`expr $INSTALL_PART_NR - 1`)%" )
### find active Windows partition
### -----------------------------------------------------------
if [ ! $WIN_PART ]; then
# try to find active Windows partition
WIN_PART=$( fdisk -l 2>/dev/null | awk '{ if ($2 == "*" && $7 ~ "NTFS") print $1 }' | head -1 )
fi
if [ $WIN_PART ]; then
WIN_installed=true
WIN_DISK=$( echo "$WIN_PART" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' )
WIN_PART_NR=$( echo "$WIN_PART" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' )
# convert dev syntax to grub syntax
GRUB_WIN_DEV=$( grep $WIN_DISK $DEVICE_MAP | awk '{ print $1 }' )
GRUB_WIN_PART=$( echo "$GRUB_WIN_DEV" | sed "s%)$%,`expr $WIN_PART_NR - 1`)%" )
# $GRUB_WIN_PART should be something like (hd0,0)
echo "Found active Windows partition ( $WIN_PART = $GRUB_WIN_PART )"
echo "Will add entry for Windows in GRUB."
echo
fi
### create grub.conf file
### -----------------------------------------------------------
echo "Create grub.conf ..."
TITLE="Linux"
[ -e $NEW/etc/redhat-release ] && TITLE=$( cat $NEW/etc/redhat-release )
DEFAULT=0
# set default=1, if smp kernel is running
uname -r | grep -q smp
[ "$?" = "0" ] && DEFAULT=1
cat > $NEW/boot/grub/grub.conf <<EOF
# grub.conf generated by $SCRIPTNAME
default=$DEFAULT
timeout=5
splashimage=$GRUB_ROOT_PART/boot/grub/splash.xpm.gz
#hiddenmenu
EOF
if [ $UP_installed ]; then
echo "Add entry for UP kernel into grub.conf"
cat >> $NEW/boot/grub/grub.conf <<EOF
title $TITLE (${KERNEL_VERSION})
root $GRUB_ROOT_PART
kernel /boot/vmlinuz-$KERNEL_VERSION ro root=$INSTALL_PART
initrd /boot/initrd-$KERNEL_VERSION.img
EOF
fi
if [ $SMP_installed ]; then
echo "Add entry for SMP kernel into grub.conf"
cat >> $NEW/boot/grub/grub.conf <<EOF
title $TITLE (${KERNEL_VERSION}smp)
root $GRUB_ROOT_PART
kernel /boot/vmlinuz-${KERNEL_VERSION}smp ro root=$INSTALL_PART
initrd /boot/initrd-${KERNEL_VERSION}smp.img
EOF
fi
if [ $WIN_installed ]; then
echo "Add entry for Windows into grub.conf"
cat >> $NEW/boot/grub/grub.conf <<EOF
title Windows
rootnoverify $GRUB_WIN_PART
chainloader +1
EOF
fi
chmod 600 $NEW/boot/grub/grub.conf
ln -s ../boot/grub/grub.conf $NEW/etc/grub.conf
ln -s ./grub.conf $NEW/boot/grub/menu.lst
echo "done."; echo
### create /etc/sysconfig/grub file
### -----------------------------------------------------------
cat > $NEW/etc/sysconfig/grub <<EOF
boot=$MBR_DEV
forcelba=0
EOF
fi
### install kernel and other files into /boot
### -----------------------------------------------------------
echo "Install kernel(s) ..."
[ -e /boot/vmlinuz ] && BOOT_DIR=/boot
[ -e /boot/boot/vmlinuz ] && BOOT_DIR=/boot/boot
if [ ! $BOOT_DIR ]; then
echo "ERROR: No kernel found - installation failed"; echo
exit_now 1
fi
cp -a $BOOT_DIR/vmlinuz $NEW/boot/vmlinuz-${KERNEL_VERSION}
cp -a $BOOT_DIR/vmlinuzs $NEW/boot/vmlinuz-${KERNEL_VERSION}smp 2>/dev/null
cp -a $BOOT_DIR/System.map-* $NEW/boot/
cp -a $BOOT_DIR/config-* $NEW/boot/
cp -a $BOOT_DIR/symvers-*.gz $NEW/boot/ 2>/dev/null
cp -a $BOOT_DIR/grub/splash.xpm.gz $NEW/boot/grub/ 2>/dev/null
cp -a $BOOT_DIR/message.ja $NEW/boot/ 2>/dev/null
cp -a $BOOT_DIR/message $NEW/boot/ 2>/dev/null
echo "done."; echo
### create /etc/sysconfig/kernel file
### -----------------------------------------------------------
cat > $NEW/etc/sysconfig/kernel <<EOF
# UPDATEDEFAULT specifies if new-kernel-pkg should make
# new kernels the default
UPDATEDEFAULT=yes
# DEFAULTKERNEL specifies the default kernel package type
DEFAULTKERNEL=kernel
EOF
### create /etc/fstab
### -----------------------------------------------------------
cat > $NEW/etc/fstab <<EOF
$INSTALL_PART / ext3 defaults 1 1
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /dev/shm tmpfs defaults 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
EOF
if [ $SWAP_PART ]; then
echo "$SWAP_PART swap swap defaults 0 0" >> $NEW/etc/fstab
fi
### make initrd
### (needs $NEW/etc/fstab to find correct modules for root filesystem !!)
### -----------------------------------------------------------
echo "Create initrd(s) ..."
# initrd should not be build on tmpfs (we take $NEW/tmp instead of /tmp)
sed -i "s|^TMPDIR=.*|TMPDIR=\"$NEW/tmp\"|" /usr/sbin/livecd-mkinitrd
if [ $UP_installed ]; then
depmod -a ${KERNEL_VERSION}
/usr/sbin/livecd-mkinitrd --fstab=$NEW/etc/fstab \
$NEW//boot/initrd-${KERNEL_VERSION}.img ${KERNEL_VERSION}
if [ ! -e $NEW/boot/initrd-${KERNEL_VERSION}.img ]; then
echo "ERROR: Failed to create $NEW/boot/initrd-${KERNEL_VERSION}.img"
exit_now 1
fi
fi
if [ $SMP_installed ]; then
depmod -a ${KERNEL_VERSION}smp
/usr/sbin/livecd-mkinitrd --fstab=$NEW/etc/fstab \
$NEW/boot/initrd-${KERNEL_VERSION}smp.img ${KERNEL_VERSION}smp
if [ ! -e $NEW/boot/initrd-${KERNEL_VERSION}smp.img ]; then
echo "ERROR: Failed to create $NEW/boot/initrd-${KERNEL_VERSION}smp.img"
exit_now 1
fi
fi
echo "done."; echo
### remove LiveCD init.d scripts
### -----------------------------------------------------------
for file in $LIVECD_INIT_SCRIPTS; do
rm -f $NEW/etc/rc.d/init.d/$file
for n in 0 1 2 3 4 5 6; do
rm -f $NEW/etc/rc.d/rc${n}.d/*$file
done
done
### restore cronjobs
### -----------------------------------------------------------
mv $NEW/etc/cron_backup/sysstat $NEW/etc/cron.d/ 2>/dev/null
mv $NEW/etc/cron_backup/cfengine $NEW/etc/cron.d/ 2>/dev/null
mv $NEW/etc/cron_backup/psi-cronjobs $NEW/etc/cron.d/ 2>/dev/null
mv $NEW/etc/cron_backup/00-makewhatis.cron.weekly $NEW/etc/cron.weekly/00-makewhatis.cron 2>/dev/null
mv $NEW/etc/cron_backup/* $NEW/etc/cron.daily/ 2>/dev/null
### prepare chroot to $NEW
### -----------------------------------------------------------
mount --bind /dev $NEW/dev
mount --bind /sys $NEW/sys
mount -t proc proc $NEW/proc
### turn on kudzu again
### -----------------------------------------------------------
chroot $NEW chkconfig kudzu on
### turn on check_update again (only at PSI)
### -----------------------------------------------------------
chroot $NEW chkconfig check_update on 2>/dev/null
### fix some services which were disabled
### because of diskless NFS client
### -----------------------------------------------------------
if [ -e /$MOUNTDIR/service.on ]; then
cat /$MOUNTDIR/service.on | while read $serv; do
chroot $NEW chkconfig $serv on
done
fi
### remove some files
### -----------------------------------------------------------
rm -rf $NEW/usr/share/applications/livecd-install-gui.desktop
rm -rf $NEW/usr/share/applications/save-localdata.desktop
### remove RPMs that can break future updates
### -----------------------------------------------------------
if [ ! $NORPMREMOVE ]; then
echo "Remove RPMs that may break future updates ..."
chroot $NEW rpm -qa 2>/dev/null > /tmp/rpmlist
# Scientific Linux RPMs
RPMSTOREMOVE="$RPMS_TO_REMOVE $RPMS_TO_REMOVE_SL"
# PSI Scientific Linux RPMs
if [ -e /etc/sysconfig/psi ]; then
RPMSTOREMOVE="$RPMS_TO_REMOVE $RPMS_TO_REMOVE_PSI"
fi
for rpm in $RPMSTOREMOVE; do
rpms_remove=$( cat /tmp/rpmlist | grep "^$rpm" )
for rpm_remove in $rpms_remove; do
chroot $NEW rpm -e --nodeps $rpm_remove >/dev/null 2>&1
[ "$?" = "0" ] && echo " removing $rpm_remove"
done
done
echo "done."; echo
fi
### disable nvidia driver
### -----------------------------------------------------------
# not in case of a PSI installation
if [ ! -e /etc/sysconfig/psi ]; then
if [ -e $NEW/etc/X11/xorg.conf.nv_SAVED ]; then
echo "Remove nvidia driver and correct xorg.conf ..."
# correct xorg.conf
sed -i "s/#nv_SAVED //" $NEW/etc/X11/xorg.conf
sed -i "/.*Driver.*nvidia.*/d" $NEW/etc/X11/xorg.conf
# disable nvidia libs (if not yet done by rpm -e)
LIB=lib
[ $( arch ) = "x86_64" ] && LIB=lib64
mv -f $NEW/usr/X11R6/$LIB/modules/extensions/xxx.libGLcore.a.saved_by_nvidia \
$NEW/usr/X11R6/$LIB/modules/extensions/libGLcore.a 2>/dev/null
mv -f $NEW/usr/X11R6/$LIB/modules/extensions/xxx.libglx.a.saved_by_nvidia \
$NEW/usr/X11R6/$LIB/modules/extensions/libglx.a 2>/dev/null
rm -f $NEW/usr/X11R6/$LIB/modules/extensions/libglx.so
rm -f $NEW/usr/X11R6/$LIB/libGL.so*
rm -f $NEW/usr/$LIB/libGLcore.so
echo "done."; echo
fi
fi
### umount $INSTALL_PART
### -----------------------------------------------------------
umount $NEW/dev
umount $NEW/sys
umount $NEW/proc
umount $INSTALL_PART
### print summary
### -----------------------------------------------------------
echo "--------------------------------------------------------------"
echo " LiveCD installed on partition $INSTALL_PART"
[ "$SWAP_PART" ] && echo " Partition $SWAP_PART will be used as swap partition"
echo
[ ! $NOGRUB ] && echo " GRUB installed in Master Boot Record (MBR) of $MBR_DEV"
[ ! $NOGRUB ] && echo " MBR saved as $MBR_FILENAME on $INSTALL_PART and in /tmp"
[ ! $NOGRUB ] && echo " If you have to restore MBR, execute under Linux:"
[ ! $NOGRUB ] && echo " # dd if=$MBR_FILENAME of=$MBR_DEV bs=512 count=1"
echo
[ $WIN_PART ] && echo " Entry created in grub.conf for Windows partition $WIN_PART"
echo "--------------------------------------------------------------"
echo "End of $SCRIPTNAME"
echo