summaryrefslogtreecommitdiffstats
path: root/rescue/tree/ka/install.sh
diff options
context:
space:
mode:
Diffstat (limited to 'rescue/tree/ka/install.sh')
-rwxr-xr-xrescue/tree/ka/install.sh635
1 files changed, 635 insertions, 0 deletions
diff --git a/rescue/tree/ka/install.sh b/rescue/tree/ka/install.sh
new file mode 100755
index 000000000..46390ecae
--- /dev/null
+++ b/rescue/tree/ka/install.sh
@@ -0,0 +1,635 @@
+#!/bin/bash
+
+# this script is run by at startup on the nfs_root system, and runs the ka-deploy client
+# it also updates the 'step file' on the tftp server
+
+# $Revision$
+# $Author$
+# $Date$
+# $Header$
+# $Id$
+# $Log$
+# Revision 1.1.2.5 2003/06/17 06:34:33 erwan
+# Removing remaining dchp cache for KA
+#
+# Revision 1.1.2.4 2003/06/11 18:04:28 erwan
+# Fixing mkreiserfs call
+#
+# Revision 1.1.2.3 2002/11/07 15:10:52 erwan
+# SCSI support now activated
+#
+# Revision 1.1.2.2 2002/11/05 15:49:13 erwan
+# added some files
+#
+# Revision 1.1.2.1 2002/11/05 11:16:54 erwan
+# added ka tools in rescue
+#
+# Revision 1.6 2001/12/03 16:28:02 sderr
+# Completely new install script
+#
+# Revision 1.5 2001/10/10 13:55:04 sderr
+# Updates in documentation
+#
+# Revision 1.4 2001/06/29 09:31:45 sderr
+# *** empty log message ***
+#
+# Revision 1.3 2001/05/31 08:51:43 sderr
+# scripts/doc update to match new command-line syntax
+#
+# Revision 1.2 2001/05/03 12:34:41 sderr
+# Added CVS Keywords to most files. Mostly useless.
+#
+# $State$
+
+# This script is provided as an exmaple and should probably not be run as is
+
+
+unset LANG
+unset LANGUAGE
+
+# needed for some for i in foo* loops
+shopt -s nullglob
+
+bash < /dev/tty2 >/dev/tty2 2>&1 &
+
+# IDEA : maybe this option could be overriden by a kaopt= in the kernel command line ?
+KA_SESSION_BASE="-s kainstall"
+
+ka_call_num=0
+
+inc_ka_session()
+{
+ (( ka_call_num++ ))
+ cur_ka_session=$KA_SESSION_BASE$ka_call_num
+}
+
+
+# testing ? -- NOT FULLY IMPLEMENTED !!!!!!!!!!!!!!!!!!!!
+#DONTWRITE=yes
+DONTWRITE=no
+
+# Let's find out what our IP is
+ip=`/sbin/ifconfig | grep -v 127.0.0.1 | grep "inet addr" | sed 's/^.*inet addr:\([^ ]*\) .*$/\1/g' | head -n 1`
+
+# the file tftpserver should contain the name of the .. tftpserver
+server=`cat tftpserver`
+
+
+# reverse a file
+tac()
+{
+ awk '{ x[NR] = $0 } END { for (i = NR; i >= 1; i--) print x[i] }'
+}
+
+# run a command, hide its output and print OK if it suceeds, print FAILED and show the output otherwise.
+runcom()
+{
+ echo -n "$1..." 1>&2
+ shift;
+ out=`"$@" 2>&1`
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo $C_S"OK"$C_N 1>&2
+ else
+ echo $C_F"Failed"$C_N 1>&2
+ echo $C_W"$out"$C_N 1>&2
+ fi
+ return $ret
+
+}
+
+# 5 4 3 2 1 zero ignition
+countdown()
+{
+ t=$1
+ while [ "$t" -ne 0 ]; do
+ echo -n "$t "
+ sleep 1
+ # move the cursor back
+ # I use now tr instead of sed because busybox's sed adds a non-wanted carriage return
+ # busybox's tr does not seem to know about the [: :] stuff (?)
+ echo -n "$t " | tr " 0-9" $'\x08'
+ (( t-- ))
+ done
+ # backspace only moves the cursor back, so at this point there's still a "1" to erase
+ if [ "$1" -ne 0 ] ;then
+ echo -n " "$'\x08\x08'
+ fi
+}
+
+
+int_shell()
+{
+ echo $C_H"starting an interactive shell"$C_N
+ exec /bin/bash
+}
+
+fail()
+{
+ echo $*
+ echo $C_F"--- The installation program FAILED ---"$C_N
+ echo "Check your configuration -- try to read previous error messages"
+ echo "This machine is going to reboot (Ctrl-S to block it) (Ctrl-C for an interactive shell)"
+ trap int_shell SIGINT
+ countdown 30
+ do_reboot
+}
+
+do_reboot()
+{
+ reboot
+ sleep 1234567 # do not continue the install script (/sbin/reboot does not block)
+}
+
+
+
+# ahem this LILO function should be fixed someday
+# right now this function assumes there is a properly configured lilo on the duplicated linux system
+do_lilo()
+{
+
+
+chroot /mnt/disk << EOF
+lilo
+EOF
+
+
+}
+
+
+run_chroot_command()
+{
+
+ chroot /mnt/disk $*
+
+}
+
+
+log()
+{
+ echo $* 1>&2
+ echo $* >> /tmp/ginstlog
+}
+
+# version for the standard tftp client
+std_tftp_put_file()
+{
+ remotef=$2
+ localf=$1
+ err=`echo put $localf $remotef | tftp $server 2>&1`
+ err=`echo $err | grep Sent`
+ if [ -z "$err" ]; then
+ log tftp error: could not get/put file
+ return 1
+ fi
+ return 0
+}
+
+# version for the tftp client built in busybox
+busybox_tftp_put_file()
+{
+ remotef=$2
+ localf=$1
+ err=`tftp -p -l $localf -r $remotef $server 2>&1`
+ if [ $? -ne 0 ]; then
+ log tftp error: could not get/put file $err
+ return 1
+ fi
+ return 0
+}
+
+
+busybox_tftp_get_file()
+{
+ remotef=$1
+ localf=$2
+ err=`tftp -g -l $localf -r $remotef $server 2>&1`
+ if [ $? -ne 0 ]; then
+ log tftp error: could not get/put file $err
+ return 1
+ fi
+ return 0
+}
+
+
+std_tftp_get_file()
+{
+ remotef=$1
+ localf=$2
+ err=`echo get $remotef $localf | tftp $server 2>&1`
+ err=`echo $err | grep Received`
+ if [ -z "$err" ]; then
+ echo tftp error: could not get/put file
+ return 1
+ fi
+ return 0
+}
+
+tftp_get_file()
+{
+ busybox_tftp_get_file "$@"
+}
+
+tftp_put_file()
+{
+ busybox_tftp_put_file "$@"
+}
+
+# write a string ($2) in a remote file ($1)
+tftp_put_in()
+{
+ echo "$2" > $temp
+ err=`echo put $temp "$1" | tftp $server 2>&1`
+ rm -f $temp
+ err=`echo $err | grep Sent`
+ if [ -z "$err" ]; then
+ log tftp error: could not get/put file
+ return 1
+ fi
+ return 0
+}
+
+get_var_bis()
+{
+ while read a; do
+ echo "$a" | grep -s -q "^ *#.*"
+ if [ $? -eq 0 ]; then
+ continue
+ fi
+ val=`echo "$a" | sed 's/[^"]*"\(.*[^\\]\)".*/\1/'`
+ var=`echo "$a" | sed 's/[^"]*".*[^\\]" *\$\([^ ]*\)/\1/'`
+ if [ "$var" = "$1" ]; then
+ echo $val
+ return 0
+ fi
+ done
+ return 1
+}
+
+# fetch variable $2 from file $1
+get_var()
+{
+ (cat $1; echo) | get_var_bis $2
+}
+
+# find the current step in the kernel command line
+get_step()
+{
+ step=install
+# step=`cat /proc/cmdline | sed 's/.*kastep=\([^ ]*\).*/\1/'`
+ if [ "$step" ]; then
+ echo $step > /tmp/step
+ return 0
+ fi
+ return 1
+}
+
+
+# write a new file on the tftp server
+# this file is a pxelinux config file
+# do this by getting the 'template file' and adding a DEFAULT at the beginning
+set_step()
+{
+ step=$1
+
+
+ runcom "Getting template file" tftp_get_file "ka/pxelinux.cfg/template" /tmp/template || return 1
+
+ echo DEFAULT $step > /tmp/newcfg
+ cat /tmp/template >> /tmp/newcfg
+
+ runcom "Sending back new pxelinux config file" tftp_put_file /tmp/newcfg "ka/pxelinux.cfg/IP/$ip" || return 1
+
+ return 0
+}
+
+
+
+# the mount_partition calls must be done in the same shell (NOT a subshell) because the global variable below has to be updated
+# idea : maybe use a file instead of this variable (and since the tac function now exists, why not ?)
+mounted_fs=""
+
+# mount a partition UNDER /disk !!! (/disk is prepended to $2)
+mount_partition()
+{
+ dev=$1
+ point=$2
+
+ echo -n "Mounting $C_H$1$C_N as /mnt/disk$C_H$point$C_N"
+ mkdir -p /mnt/disk$point
+ test -d /mnt/disk$point || return 1
+ runcom "..." mount $dev /mnt/disk/$point || return 1
+ mounted_fs="$dev $mounted_fs"
+ return 0
+}
+
+# umount all mounted partitions under /disk, in the reverse order
+umount_partitions()
+{
+ for dev in $mounted_fs; do
+ retries=0
+ while ! runcom "Umounting $dev" umount $dev ; do
+ sleep 3
+ (( retries++ ))
+ if [ $retries -gt 3 ]; then
+ echo Failed too many times. giving up.
+ break
+ fi
+ done
+ done
+}
+
+
+# recreate excluded directories
+# read stdin like this : u=rwx g=rwx o=rwx uid gid filename
+recreate_dirs()
+{
+ while read line; do
+ declare -a fields
+ fields=( $line )
+ file=/mnt/disk/${fields[5]}
+# echo $file
+# note : it is possible that the directory exists already, if it was a mount point
+# we need to set the permissions/users anyway
+ mkdir -p $file
+# echo chmod ${fields[0]},${fields[1]},${fields[2]} $file
+ chmod ${fields[0]},${fields[1]},${fields[2]} $file
+ # argl !! chmod o+t does not work with busybox's chmod !
+ # we have to handle it alone
+ if echo ${fields[2]} | grep -q t; then
+ chmod +t $file
+ fi
+ chown ${fields[3]}.${fields[4]} $file
+ done
+}
+
+make_partitions()
+{
+ # we must be in the partfiles directory
+ for file in partition_tab*; do
+ drive=`echo $file | sed 's/partition_tab//'`
+ cat $file | runcom "Writing partition table for $drive using sfdisk" /sbin/sfdisk /dev/$drive -uS --force || fail "error with sfdisk"
+ done
+
+ for file in fdisk_commands*; do
+ drive=`echo $file | sed 's/fdisk_commands//'`
+ runcom "Cleaning hard drive" dd if=/dev/zero of=/dev/$drive bs=1M count=5 || fail "Can t clean drive$drive"
+ cat $file | runcom "Writing partition table for $drive using fdisk" fdisk /dev/$drive || fail "error with fdisk"
+ done
+
+}
+checkDevEntries()
+{
+ if ! test -r /mnt/disk/dev/hda ; then
+ (cd /dev && tar c *) | (cd /mnt/disk/dev && tar x)
+ fi
+}
+
+write_MBRs()
+{
+# we must be in the partfiles directory also
+ for file in MBR*; do
+ drive=`echo $file | sed 's/MBR//'`
+ runcom "Writing new MBR for $drive" dd if=$file of=/dev/$drive bs=1 count=446
+ done
+}
+
+
+# Colors
+# Success
+C_S=$'\033[1;32m'
+# Failure
+C_F=$'\033[1;31m'
+# Warning
+C_W=$'\033[1;33m'
+# Normal
+C_N=$'\033[0;39m'
+# Hilight
+C_H=$'\033[1;39m'
+
+
+# Clear screen, fancy startup message.
+echo $'\033'[2J$'\033'[H
+echo "------| $C_H"Ka"$C_N |---- Install starting..."
+
+temp=/tmp/ginst
+
+# activate dma ? -- obsolete stuff I think
+# runcom "Setting HD optimizations" hdparm -c1 -d1 -K1 $HD
+
+delay=0
+
+if ! runcom "Getting step name" get_step; then
+ echo "Error: Could not get current step "
+ fail
+else
+ step=`cat /tmp/step`
+fi
+
+echo Next Server is `cat /ka/tftpserver`
+
+echo Current step for $ip is : \"$C_H$step$C_N\"
+
+echo -n "Finding install type : "
+case $step in
+ shell)
+ echo No install, but interactive shell
+ ## drop the user to an interactive shell
+ exec /bin/bash
+ ;;
+ install)
+ install_type=install
+ nextstep=ready
+ echo Install Linux
+ ;;
+ test_install)
+ install_type=test_install
+ nextstep=ready
+ echo TEST TEST TEST
+ countdown 10
+ echo Install Linux TEST
+ ;;
+esac
+
+
+if [ -z "$install_type" ]; then
+ echo FATAL : Could not recognize this step name
+ echo "Aborting... "
+ fail
+fi
+
+
+
+# receive the partition table, fstab, etc from the source node
+mkdir /tmp/partfiles
+inc_ka_session
+echo Current session is $cur_ka_session
+runcom "Receiving partitions information" /ka/ka-d-client -w $cur_ka_session -e "( cd /tmp/partfiles && tar xvf - )" || fail
+
+
+
+
+cd /tmp/partfiles
+make_partitions
+
+
+test -f /tmp/partfiles/streams || fail "Missing streams file"
+first_stream=`cat /tmp/partfiles/streams | head -n 1`
+
+if [ "$first_stream" = linux ]; then
+ rcv_linux=yes
+else
+ rcv_linux=no
+fi
+
+
+
+#if we must receive a linux system, we need to format and mount the partitions
+if [ $rcv_linux = yes ]; then
+ # format partitions
+ format_partitions()
+ {
+ while read line; do
+ declare -a fields
+ fields=( $line )
+
+ case ${fields[2]} in
+ reiserfs )
+ runcom "Formatting ${fields[0]} as reiserfs" mkreiserfs -f ${fields[0]} || fail
+ ;;
+ jfs )
+ runcom "Formatting ${fields[0]} as jfs" mkfs.jfs ${fields[0]} || fail
+ ;;
+
+ xfs )
+ runcom "Formatting ${fields[0]} as xfs" mkfs.xfs -f ${fields[0]} || fail
+ ;;
+ ext3 )
+ runcom "Formatting ${fields[0]} as ext3" mkfs.ext2 -j ${fields[0]} || fail
+ ;;
+ ext2 )
+ runcom "Formatting ${fields[0]} as ext2" mkfs.ext2 ${fields[0]} || fail
+ ;;
+ swap )
+ runcom "Formatting ${fields[0]} as swap" mkswap ${fields[0]} || fail
+ ;;
+ esac
+ done
+ }
+
+ format_partitions < /tmp/partfiles/pfstab
+
+
+ # mount the partitions
+
+ mount_partitions()
+ {
+ while read line; do
+ declare -a fields
+ fields=( $line )
+
+ case ${fields[2]} in
+ reiserfs )
+ mount_partition ${fields[0]} ${fields[1]} || fail
+ ;;
+ xfs )
+ mount_partition ${fields[0]} ${fields[1]} || fail
+ ;;
+ jfs )
+ mount_partition ${fields[0]} ${fields[1]} || fail
+ ;;
+ ext3 )
+ mount_partition ${fields[0]} ${fields[1]} || fail
+ ;;
+ ext2 )
+ mount_partition ${fields[0]} ${fields[1]} || fail
+ ;;
+ esac
+ done
+ }
+
+ # NOTE
+ # I replaced cat truc | mount_partitions by mount_partitions < truc
+ # because in the former case mount_partitions runs in a subshell and the $mounted_fs value is lost
+ mount_partitions < /tmp/partfiles/pfstab
+
+ echo ++++++++++++++++++++++++++
+ mount
+ echo ++++++++++++++++++++++++++
+
+ delay=0
+else
+ delay=10
+fi
+
+if [ $DONTWRITE != yes ]; then
+ for stream in `cat /tmp/partfiles/streams`; do
+ if [ "$stream" = "linux" ]; then
+ # partitions already formatted/mounted, just copy now
+ # untar data from the master 'on the fly'
+ echo -n "Linux copy is about to start "
+ countdown $delay
+ echo
+ inc_ka_session
+ /ka/ka-d-client -w $cur_ka_session -e "(cd /mnt/disk; tar --extract --read-full-records --same-permissions --numeric-owner --sparse --file - ) 2>/dev/null" || fail
+ echo Linux copy done.
+ echo Creating excluded directories
+ cat /tmp/partfiles/excluded | recreate_dirs
+ echo Setting up networking
+ /ka/setup_network.sh
+ delay=10
+ else
+ # maybe receive some raw partition dumps
+ echo Raw copy of $stream is about to start
+ countdown $delay
+ inc_ka_session
+ /ka/ka-d-client -w $cur_ka_session -e "dd of=$stream bs=65536" || fail
+ delay=10
+ fi
+ done
+
+ echo "Removing computing interfaces"
+ rm -f /mnt/disk/etc/sysconfig/network-scripts/ifcfg-eth1 >/dev/null 2>&1
+
+ echo "Removing duplicated dhcp cache"
+ rm -f /mnt/disk/etc/dhcpc/* >/dev/null 2>&1
+
+ echo "Writing modules.conf"
+ /usr/bin/perl /ka/gen_modules_conf.pl >/mnt/disk/etc/modules.conf
+
+ runcom "Syncing disks" sync
+
+ echo "Running mkinitrd"
+ /ka/make_initrd
+
+ cd /tmp/partfiles
+ write_MBRs
+
+
+ if test -f /tmp/partfiles/command; then
+ checkDevEntries
+ command_to_run=`cat /tmp/partfiles/command`
+ runcom "Running $command_to_run" run_chroot_command "$command_to_run"
+ fi
+
+else
+ echo " I would run ka-deploy(s) and then lilo/mbr "
+ sleep 1
+fi
+
+# maybe there is a last dummy ka-deploy for synchronization
+if test -f /tmp/partfiles/delay; then
+ sleep 1
+ inc_ka_session
+ runcom "Waiting source node signal to end installation" /ka/ka-d-client -w $cur_ka_session -e "cat" || fail
+fi
+
+umount_partitions
+
+
+# Update the step file on the tftp server
+#runcom 'Sending back new $step' set_step $nextstep || fail
+
+echo -n Rebooting...
+countdown 3
+do_reboot