+*) 2004-12-08
+
+- finished minimal fai concepts
+- added some documentation for fai
+
*) 2004-12-07
- added fai directory including new rc_fai.sh script
------
./scripts/Create-FAI
+./fai/*
./doc/FAI
procedure
the install process. fai-server is actually the target you will
need as a running system to have pxeboot/nfsutils and stuff.
- ./scripts/Create-FAI
+ note: you might want to fetch hdw binaries from a mirror.
+ edit your /etc/hdw-get.conf file.
+
+ ./scripts/Create-FAI <nfsroot>
+
+ where <nfsroot> is the directory to install the fairoot.
2) edit the following files to match your needs, and restart services
(have a look at chapter "fai server configuration")
+ note: again you might want to use a mirror. edit hdw-get.conf, but make
+ sure it is the one from fairoot.
+
3) adapt configs in ./fai (see chapter "fai config files")
- 4) pxeboot your install candidates and watch installation
+ 4) pxeboot your install candidates. this is actually not fully
+ automated.
+
+ - type "fai" on pxeboot prompt
+ - after first bootup, use cfdisk to partition your harddisk
+ - touch a disk_ready file in configuration space
+ (after using cfdisk, sync to disk file!)
+ - reboot and finaly wathc your target system to get hdw'ed :)
+
+ 5) login, build a new kernel. copy new bzImage to /boot/vmlinuz_hdw
+ and run lilo again. reboot and enjoy! good luck.
fai config files
----------------
+ config files reside in 1) ./fai/config/<client_ip>/ and 2) ./fai/files/
+ directories.
+
+ config dir:
+
+ - the files reside in a subdirectory, which is simply the
+ clients ip address, as different clients may need different
+ config.
+ - files:
+ 1) disk
+ 2) packages
+
+ disk file is used to determine the partition layout and
+ used harddisk. the format: (example, its intuitive!)
+
+ # disk /dev/hda
+ # swap 7
+ 1 /boot ext3 format
+ 5 / ext3 format
+ 6 /home ext3 preserve
+
+ packages file contains packages to get installed. you
+ may use ./scripts/Helper -create_dist_files to create
+ one. make sure that all the packages are available on
+ the mirror, otherwise the fai install routine will
+ break. hint: switch the partitions to "preserve" and
+ hdw-get will not install already installed packages
+ again.
+
+ files dir:
+
+ - files called DEFAULT in a special directory will be copied to
+ every client to the file of its dirname.
+ - files named like a clients ip address will be only copied to
+ that client (again, the file will be the dirname)
+
+ example:
+
+ ./fai/files/etc/X11/XF86Config/DEFAULT will be copied to all
+ clients as /etc/X11/XF86Config file.
+
+
fai server configuration
------------------------
-[to be continued]
+there are several files you need to hack. here we go:
+
+ - dhcpd:
+
+ file: /etc/dhcpd.conf
+
+ examples rule, have a look at the configuration for my fai
+ client:
+
+ ...
+ option routers 192.168.10.10;
+ option domain-name-servers 192.168.10.50, 194.25.134.203;
+ host compaq {
+ fixed-address 192.168.10.80;
+ hardware ethernet 00:50:8b:cb:8e:d2;
+ allow booting;
+ allow bootp;
+ next-server hackstation; # the fai server
+ server-name hackstation;
+ filename "pxelinux.0";
+ }
+ ...
+
+ - tftpboot (you will need tftp-hpa as tftpserver)
+
+ the scripts prepared a working fai config file at
+ /tftpboot/pxelinux.cfg, just add a symbolic link of your clients
+ ip address (in hex, use: gethostip) pointing to fai.
+ ofcourse you need to have the package syslinux installed.
+
+ - nfsd:
+
+ file: /etc/exports
+
+ the scripts added export entries. just substitute "foobar" to
+ the name or ip address of your fai clients.
+
+ - inetd
+
+ file: /etc/inetd.conf
+
+ make sure the tftpboot line is uncommented. if you have problems
+ of tftpd switching to user nobody google for solutions. if you
+ are too lazy substitute "nobody" by "root in inetd.conf. this
+ is dangerous though, you have been warned.
+
+note: restart all the mentioned services.
+
+troubleshooting
+---------------
+
+contact me! -> http://www.hackdaworld.dyndns.org/contents/contact/
+email: hackbard@hackdaworld.dyndns.org
+irc: irc.hackdaworld.dyndns.org - #hackdaworld
+
+greets
+------
+
+good luck now, you are own your own! enjoy hdw. :)
+
+regards, hackbard.
croot=/fai/config
myip="`ifconfig eth0 | grep inet\ addr | awk '{ print $2 }' | awk -F: '{ print $2 }'`"
myconf=$croot/$myip
+proot=""
if [ ! -d $myconf ] ; then
echo "no config found, aborting fai"
exit
fi
+echo "debug:"
+route
+ifconfig
+
+#
+# we need writeable /tmp
+#
+mount -tramfs ramfs /tmp
+
+#
+# check if disk is ready
+#
+if [ ! -f $croot/$myip/disk_ready ] ; then
+ echo
+ echo "you're disk seems to not be ready. login now and use cfdisk"
+ echo "to partition your harddisk. please make sure it's compatible"
+ echo "to $croot/$myip/disk:"
+ cat $croot/$myip/disk
+ echo
+ echo "after partitioning your harddisk please touch the file"
+ echo "$croot/$myip/disk_ready"
+ echo "on your fai install server and reboot."
+ echo "... fully automated, he? :p"
+ echo
+ exit
+fi
+
+#
+# disk
+#
disk=0
disk=`grep '#\ disk' $myconf/disk | awk '{ print $3 }'`
if [ ! -b $disk ] ; then
mkswap ${disk}${swap}
echo "done"
fi
-
-cat $myconf/disk | grep -v '^#' | while read nr mp; do
+cat $myconf/disk | grep -v '^#' | while read nr mp fs ac; do
if [ -b ${disk}${nr} ] ; then
- echo "making filesystem for $mp"
- mke2fs -j ${disk}${nr}
+ action=""
+ [ "$fs" = "ext3" ] && action="mke2fs -j"
+ [ "$fs" = "ext2" ] && action="mke2fs"
+ if [ "$ac" = "format" -a -n "$action" ] ; then
+ echo "making filesystem for $mp"
+ $action ${disk}${nr}
+ fi
if [ "$mp" = "/" ] ; then
echo "mounting root partition"
mount ${disk}${nr} $root
+ mkdir -p $root/etc
+ grep -v '/dev/root' /etc/fstab > $root/etc/fstab
+ echo -e "${disk}${nr}\t$mp\t$fs\tdefaults 0 2" >> \
+ $root/etc/fstab
+ proot=${disk}${nr}
fi
fi
done
-
-cat $myconf/disk | grep -v '^#' | while read nr mp; do
+cat $myconf/disk | grep -v '^#' | while read nr mp fs ac; do
if [ "$mp" != "/" ] ; then
if [ -b ${disk}${nr} ] ; then
mkdir -p $root/$mp
mount ${disk}${nr} $root/$mp
+ echo -e "${disk}${nr}\t$mp\t$fs\tdefaults 0 2" >> \
+ $root/etc/fstab
fi
fi
done
+# packages might install new fstab file, stored.
+cp $root/etc/fstab $root/etc/fstab~
+
+#
+# install packages
+#
+cd /tmp # we need to wget stuff!
+pkglist=""
+[ -f /fai/config/$myip/packages ] && pkglist=/fai/config/$myip/packages
+if [ -z "$pkglist" ] ; then
+ echo "cant find package list for $myip, aborting"
+ exit
+fi
+hdw-get dist-install $root $pkglist
+
+#
+# config / files
+#
+cp $root/etc/fstab~ $root/etc/fstab
+cp /etc/hdw-get.conf $root/etc
+# files
+cd /fai/files
+for file in `find -type f | grep -v CVS`; do
+ srcf=`basename $file`
+ trgf=`dirname $file`
+ [ "$srcf" = "DEFAULT" -o "$srcf" = "$myip" ] && cp -v $file $root/$trgf
+done
+
+#
+# essential device file
+#
+[ ! -c $root/dev/null ] && mknod -m 0666 $root/dev/null c 1 3
+[ ! -c $root/dev/console ] && mknod -m 0600 $root/dev/console c 5 1
+
+
+#
+# lilo
+#
+cat > $root/etc/lilo.conf << EOF
+boot=$disk
+prompt
+lba32
+timeout=30
+
+default=vmlinuz_hdw
+
+image=/boot/vmlinuz_hdw
+ label=vmlinuz_hdw
+ append="root=$proot"
+ read-only
+
+EOF
+# run lilo in chroot
+cat > $root/run_lilo.sh << EOF
+mount /dev
+mount /sys
+mount /proc
+udevstart
+mount -a
+ln -s /proc/self/fd /dev/fd
+ln -s /proc/self/fd/0 /dev/stdin
+ln -s /proc/self/fd/1 /dev/stdout
+ln -s /proc/self/fd/2 /dev/stderr
+ln -s /proc/kcore /dev/core
+lilo
+EOF
+chmod 755 $root/run_lilo.sh
+chroot $root /usr/bin/env PATH="/bin:/usr/bin:/sbin:/usr/sbin" /bin/bash \
+ --login +h /run_lilo.sh
+
+echo
+echo "fai finished, good luck for reboot ... :)"
+echo
-echo "to be continued ...."
+touch /tmp/fai_finished
exit 0
--- /dev/null
+#!/bin/sh
+#
+# hdw - linux /etc/init.d/boot (copied from ROCK Linux + modifications)
+#
+# modified for fai routine
+#
+
+exec 2>&1
+
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/fai/scripts
+
+echo "** booting hdw-linux FAI routine ... **"
+
+mount -v -n /dev
+mount -v -n /proc ; mount -v -n /sys
+mkdir -p /dev/shm ; mount -v -n /dev/shm
+mkdir -p /dev/pts ; mount -v -n /dev/pts
+
+echo "loading kernel modules and configuring the kernel ..."
+. /etc/conf/kernel
+
+echo "populating device nodes ..."
+/etc/init.d/udev start
+
+if [ -f /etc/conf/devfs ] ; then
+ echo "configuring device nodes ..."
+ . /etc/conf/devfs
+fi
+
+echo "activating swap-devices ..."
+swapon -a
+
+mount -v -n -o remount,rw /
+mount -v -a -t nocoda,nfs
+
+if type hostname > /dev/null 2>&1
+then
+ echo "set the hostname to [`cat /etc/HOSTNAME`] ..."
+ hostname `cat /etc/HOSTNAME`
+else
+ echo "hostname not set: no 'hostname' command found"
+fi
+
+if type loadkeys > /dev/null 2>&1
+then
+ echo "set the keyboard keymappings ..."
+ if [ -L /etc/default.keymap ] ; then
+ oldpwd="`pwd`" ; cd /etc
+ loadkeys `ls -l default.keymap | tr -s ' ' | cut -f11 -d' '`
+ cd "$oldpwd" ; unset oldpwd
+ elif [ -f /etc/default.keymap ] ; then
+ loadkeys /etc/default.keymap
+ else
+ echo "no /etc/default.keymap found."
+ fi
+else
+ echo "keymappings not configured: no 'loadkeys' command found."
+fi
+
+if type ifconfig > /dev/null 2>&1
+then
+ echo "setting up loopback networking ..."
+ ifconfig lo 127.0.0.1 netmask 255.0.0.0 up
+ route add -net 127.0.0.0 netmask 255.0.0.0 dev lo
+fi
+
+echo 'setting overflow UID and GID kernel parameters ...'
+sysctl -w kernel.overflowuid=`id -u nobody` | tr -d '\n'
+echo -n ', ' ; sysctl -w kernel.overflowgid=`id -g nobody`
+
+echo "initializing kernel random number generator ..."
+[ -f /var/state/random-seed ] && cat /var/state/random-seed >/dev/urandom
+
+echo
+echo
+echo "start of FAI (fully automated installation) process, good luck ..."
+echo
+echo
+echo -en "starting portmap ..."
+/usr/sbin/portmap
+echo " done"
--- /dev/null
+#!/bin/sh
+#
+# hdw - linux /etc/init.d/rc (modified for fai)
+#
+# controls switching of runlevels (copied from ROCK Linux)
+#
+
+exec 2>&1
+
+export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/fai/scripts
+
+echo "** running rc (fai) script **"
+
+echo "RC: Previous runlevel: $PREVLEVEL, current runlevel: $RUNLEVEL."
+
+curdir=/etc/init.d/rc$RUNLEVEL.d
+prevdir=/etc/init.d/rc$PREVLEVEL.d
+
+#
+# run the KILL scripts of the previous runlevel (if needed)
+#
+if ! [ $PREVLEVEL = S -o $PREVLEVEL = N ]
+then
+ echo "RC: Leave runlevel $PREVLEVEL ..."
+ for i in $prevdir/K*; do
+ test -x "$i" || continue
+ x="`echo "$i" | sed "s,$prevdir/K..,$curdir/S??,"`"
+ [ "`echo $x`" = "$x" ] || continue ; unset x
+ $i stop < /dev/null
+ done
+fi
+
+echo "RC: Enter runlevel $RUNLEVEL ..."
+
+if [ $RUNLEVEL = S ]
+then
+ #
+ # Kill all processes
+ #
+ echo "Sending all processes a SIGTERM (15) ..."
+ killall5 -15
+ sleep 5
+ echo "Sending all processes a 2nd SIGTERM (15) ..."
+ killall5 -15
+ sleep 3
+ echo "Sending all processes a SIGKILL (9) ..."
+ killall5 -9
+ sleep 3
+elif [ $RUNLEVEL = 0 -o $RUNLEVEL = 6 ]
+then
+ #
+ # shut down the system
+ #
+ if [ $RUNLEVEL = 0 ] ; then
+ mode=halt ; else mode=reboot ; fi
+ /etc/init.d/down $mode
+ exit 0
+else
+ #
+ # run the START scripts of the current (new) runlevel
+ #
+ for i in $curdir/S*; do
+ test -x "$i" || continue
+ x="`echo "$i" | sed "s,$curdir/S..,$prevdir/K??,"`"
+ [ "`echo $x`" = "$x" ] || continue ; unset x
+ $i start < /dev/null
+ done
+fi
+
+echo "mounting fai config space ..."
+FAI_MOUNT_LINE
+echo "done"
+
+echo "executing rc_fai.sh script ..."
+/fai/scripts/rc_fai.sh
+echo
+
+if [ -f /tmp/fai_finished ] ; then
+ echo
+ echo "FAI finished - congrats :)"
+ echo
+ echo "you may login as root (passwd = hdw), chroot to /trg and"
+ echo "build a new kernel. copy the new bzImage to /boot/vmlinuz_hdw"
+ echo "and run lilo. imho this has to be done as we only have a nfsroot"
+ echo "kernel image searching init on a nfsroot. i might be wrong here."
+ echo
+else
+ echo "login: root | passwd = hdw"
+fi
+
+exit 0
echo "pretending default target for nfsroot install now"
export hdw_target=default
+ echo "hdw_target=default # FAI_WAS_HERE" >> Config # dirty!
./scripts/Helper -create_dist_files
export hdw_target=$hdw_orig_target
+ grep -v '# FAI_WAS_HERE' Config > tmp~
+ mv tmp~ Config
echo "orig target restored to $hdw_target"
cp ./distro/default ./fai/nfsroot-packages
-fi
-echo "deleting some packages from list now"
-del="linux-libc-headers man-pages binutils gcc m4 autoconf automake"
-del="$del man make patch bin86 nasm lilo cvs"
-del="$del bootdisk" # just by now - may contain kernel image later
-for package in $del; do
- grep -v ^$package ./fai/nfsroot-packages > ./fai/tmp~
- mv ./fai/tmp~ ./fai/nfsroot-packages
-done
+ echo "deleting some packages from list now"
+ del="linux-libc-headers man-pages binutils gcc m4 autoconf automake"
+ del="$del man make patch bin86 nasm lilo cvs"
+ del="$del bootdisk" # just by now - may contain kernel image later
+ for package in $del; do
+ grep -v ^$package ./fai/nfsroot-packages > ./fai/tmp~
+ mv ./fai/tmp~ ./fai/nfsroot-packages
+ done
+ echo "adding needed packages to list now"
+ echo "portmap" >> ./fai/nfsroot-packages
+ [ "$hdw_arch" = "ia32" ] && echo "lilo" >> ./fai/nfsroot-packages
+fi
if [ ! -f $fairoot/packages_installed ] ; then
echo "creating nfsroot..."
if [ ! -f $fairoot/prepared_nfsroot ] ; then
echo "preparing nfsroot for automated install routine ..."
cd $fairoot
- mknod -m 0666 dev/null c 1 3
- mknod -m 0600 dev/console c 5 1
- grep -v swap etc/fstab > tmp~
- mv tmp~ etc/fstab
+ # special files (null & console)
+ [ ! -c dev/null ] && mknod -m 0666 dev/null c 1 3
+ [ ! -c dev/console ] && mknod -m 0600 dev/console c 5 1
+ # fstab
+ cp $home_dir/misc/sysfiles/etc/fstab ./etc
+ # the target directory
mkdir -p ./trg
+ # dir for mounting fai config
+ mkdir -p fai
+ # removing some services
for i in sysklogd network inetd nscd; do
rm -f etc/init.d/rc2.d/*${i}
done
- sed "s%^exit\ 0%mount -tnfs $myip:/$home_dir/fai /fai%" \
- etc/init.d/rc > tmp~
- mv tmp~ etc/init.d/rc
+ # modified inittab, rc and bootscript
+ sed "s%| /sbin/btee .*%%g" $home_dir/misc/sysfiles/etc/inittab > \
+ etc/inittab
+ cp $home_dir/misc/fai/fai_boot ./etc/init.d/boot
+ sed "s%^FAI_MOUNT_LINE%mount -tnfs $myip:/$home_dir/fai /fai%" \
+ $home_dir/misc/fai/fai_rc > etc/init.d/rc
chmod 755 etc/init.d/rc
- echo "/fai/scripts/rc_fai.sh" >> etc/init.d/rc
- echo "shutdown -r now" >> etc/init.d/rc
+ # modify hdw-get.conf
+ sed "s%hdw_arch_opt=.*%hdw_arch_opt=$hdw_arch_opt%" etc/hdw-get.conf > \
+ tmp~
+ mv tmp~ etc/hdw-get.conf
+ # get to home_dir again
cd $home_dir
echo "done"
touch $fairoot/prepared_nfsroot
+else
+ echo "nfsroot seems to be prepared already"
+ echo "(del $fairoot/prepared_nfsroot to recreate it)"
fi
echo "checking pxe/nfs environment ..."
cp /usr/lib/syslinux/pxelinux.0 /tftpboot
fi
mkdir -p /tftpboot/pxelinux.cfg
-echo -e "LABEL fai" > /tftpboot/pxelinux.cfg/fai
-echo -e "\tKERNEL vmlinuz_hdw" >> /tftpboot/pxelinux.cfg/fai
-echo -e "\tAPPEND root=/dev/nfs nfsroot=$myip:$fairoot ip=dhcp" >> \
- /tftpboot/pxelinux.cfg/fai
-echo -e "\tPROMPT 1" >> /tftpboot/pxelinux.cfg/fai
+cat > /tftpboot/pxelinux.cfg/fai << EOF
+PROMPT 1
+DEFAULT disk
+TIMEOUT 200
+
+LABEL fai
+ KERNEL vmlinuz_hdw
+ APPEND root=/dev/nfs nfsroot=$myip:$fairoot ip=dhcp
+
+LABEL disk
+ LOCALBOOT 0
+EOF
echo -e "$fairoot\tfoobar(async,ro,no_root_squash)" >> /etc/exports
echo -e "$home_dir/fai\tfoobar(async,ro,no_root_squash)" >> /etc/exports