#! /bin/sh # # Description: Script for generating dxs filesystem by # cloning from rsync source for Diskless X Stations (v4.0) # # Author(s): Nico Dietrich # Dirk von Suchodoletz , 02-11-2005 # # Copyright: (c) 2003, 2005 - RZ Universitaet Freiburg # header() { echo echo "Welcome to the LD4 installation" echo } # check needed things for installation precheck() { # check if running as root if [ "`id -u`" != "0" ]; then echo -e "\nYou don't have the needed permission. Please rerun as root user!\n" exit 1 fi # check for existing programs: # rsync (server-side) which rsync >/dev/null if [ $? != 0 ] ; then echo -e "\nYou need to install rsync on server side before installing!\n" exit 1 fi # ssh, rsync (referenz-system-side) -> not possible in precheck # nfs-kernel-server, atftpd # -> not needed for installation } # ask question variable_name default_value ask() { echo echo "$1" echo -n "* [ $3 ] " read userinput if [ -z "$userinput" ] ; then local back=$3 else local back="$userinput" fi eval "$2=\"$back\"" sed -e '/'$2'=.*/d' -i .config echo "$2=\"$back\"" >> .config } distro_check() { case "${!1}" in Debian*|debian*|Sarge*|sarge*) eval "$1=\"debian\"" case "${!2}" in Sarge*|sarge*|3.1*|*) eval "$2=\"3.1\"" ;; esac ;; Ubuntu*|ubuntu*) eval "$1=\"ubuntu\"" case "${!2}" in Breezy*|breezy*|*) eval "$2=\"5.10\"" ;; esac ;; Gentoo*|gentoo*) eval "$1=\"gentoo\"" case "${!2}" in 2005*|*) eval "$2=\"2005.1\"" ;; esac ;; SuSE*|suse*|Suse*|SuSe*|SUSE*|*) eval "$1=\"suse\"" case "${!2}" in 9*) eval "$2=\"9.3\"" ;; 10.0) eval "$2=\"10.0\"" ;; 10*|*) eval "$2=\"10.1\"" ;; esac ;; esac } # what do we do here?? configure() { export LANG="c" if [ -f .config ] ; then echo -n "Use values from last installation? [Y/n] " read userinput if [ "x$userinput" = "xn" ] ; then cp .config.default .config fi else cp .config.default .config fi . .config # FIXME!! network autodetection seems not to work correctly if ! [ -z "${netmask}" -a -z "${broadcast}" -a -z "${netname}" -a -z "${server}" ] ; then ipcfg=( `ifconfig eth0 | grep "inet addr" | sed -e "s,[a-zA-Z]*:,,g"` ) netmask=${ipcfg[3]} broadcast=${ipcfg[2]} # quickhack (more intelligent solution needed ...) netname=`route -n | grep -m 1 eth0 | grep -v "UG" | awk '{ print $1 }'` server=${ipcfg[1]} fi # try to detect server architecture if [ -z "${server_distro}" ] ; then for i in /bin/lsb_release /usr/bin/lsb_release; do if [ -e $i ] ; then $i > /dev/null 2>&1 || break server_distro=`. $i -i | sed "s/.*\t//"` server_distro_ver=`. $i -r | sed "s/.*\t//"` break fi done fi # if still no distro name set, try to find it using significant files if [ -z "${server_distro}" ] ; then if [ -e ${rootdir}/etc/SuSE-release ] ; then server_distro=suse server_distro_ver=`grep "VERSION" /etc/SuSE-release | sed "s/.*= //"` elif [ -e /etc/lsb-release ] ; then . /etc/lsb-release server_distro=${DISTRIB_ID} server_distro_ver=${DISTRIB_RELEASE} elif [ -e /etc/debian_version ] ; then server_distro=debian server_distro_ver=`cat /etc/debian_version` fi fi # das grosse frage-antwort-spiel: ask "Server distribution (e.g. debian): " server_distro ${server_distro} #ask "Server distribution version: " server_distro_ver ${server_distro_ver} distro_check server_distro server_distro_ver echo "Using ${server_distro} as server distribution" # ask for client distro ask "Client distribution (e.g. debian): " client_distro ${client_distro} ask "Client distribution version (numerical - e.g. 3.1): " client_distro_ver ${client_distro_ver} distro_check client_distro client_distro_ver echo "Using ${client_distro} as client distribution" if [ -z ${rootdir} ] ; then rootdir="/nfsroot/"${client_distro}-${client_distro_ver} fi . distro-specs/config-${server_distro} ask "Path for client system: " rootdir $rootdir ask "Path for tftpboot: " tftpbootdir $tftpbootdir ask "Which network do you want to use for DXS? (A.B.C.0) " netname $netname ask "Which netmask should be used? (255.B.C.0): " netmask $netmask ask "What is your servers IP for NFS, DHCP and TFTP? " server $server # noetig?? ask "Broadcast Address: " broadcast $broadcast # evtl. optional? --> besser in ein komplett eigenes Setup-Skript fuer # machine-setup ask "Where automount home directories from? (A.B.C.D:/home-dir)" amt $server":/home" # more information here!! set useful default ask "Which debug level should be used? " debuglevel $debuglevel # wo ist das referenzsystem? - was ist default ??? if [ -z ${rsyncsource} ] ; then rsyncsource="localhost:/" ; fi ask "IP + Path to reference system: " rsyncsource $rsyncsource # dns-server # domain-name # evtl. ntp-server # which kernel(s) to use to generate initial ramdisk(s) # list available kernels and allow to chose from # nfs / nbd / squash-fs? # password for pxeboot-menu (caution: you can easily retrieve it in clear # text!!) pxe_passwd="master" } copy_system() { echo -e "\n\nSyncing system now\nPlease enter root password of client machine\n" rsync -avDe ssh --delete --exclude-from=distro-specs/exclude-${client_distro}-${client_distro_ver} ${rsyncsource} ${rootdir} || { echo "Rsync failed" ; exit 1 ; } # generate error message in case rsync didn't work and exit. # TODO: mksquashfs (background process) } create_initrd() { # find existing kernels declare -i i=0 for kern in `find ${rootdir}/boot |grep vmlinuz` ; do if ! [ -L $kern ] ; then kernel[$i]=$kern i=$i+1 fi done if [ $i -eq 0 ] ; then echo "No kernels found in ${rootdir}/boot, so no initial ramdisk is created and linked to ${tftpbootdir}." kernel_choice="" elif [ $i -eq 1 ] ; then echo "Found one kernel in ${rootdir}/boot." kernel_choice="0" else echo -e "\n\nThis is a list of existing kernels in your client OS: \n" declare -i j=0 while [ $j -lt $i ] ; do echo "$j: ${kernel[$j]}" j=$j+1 done ask "Please chose kernels to create initial ramdisks for (space separated numbers) " kernel_choice ${kernel_choice} fi choice=( ${kernel_choice} ) # make sure /$tftbootdir exists mkdir -p ${tftpbootdir} declare -i j=0 # FIXME: mkdxsinitrd currently wants to run from own directory # ugly workaround... cd ../initrd while [ $j -lt ${#choice[@]} ] ; do current_kernel=${kernel[$j]#${rootdir}/boot/vmlinuz-} echo "Creating initial ramdisk for ${current_kernel}" current_initrd=${tftpbootdir}/initrd-dxs-${current_kernel} [ -f ${current_initrd} ] && rm ${current_initrd} ./mkdxsinitrd -r ${rootdir} -k ${current_kernel} -i ${current_initrd} ln -sf ${kernel[$j]} ${tftpbootdir}/vmlinuz-${current_kernel} j=$j+1 done cd - } # setting up server site configuration files etc. setup_server () { echo -e "\n\nSetting up server configuration\n" timestamp=`date +%Y%m%d-%H%M` # creating central dxs configuration directory structure if it doesn't exist for dir in dhcp nfs atftpd pxelinux client.cfg ; do [ -d ${dxs_conf}/${dir} ] || mkdir -p ${dxs_conf}/${dir} done # copy the client configuration default file - machine-setup cp default_files/machine-setup_default \ ${client_conf} # creating new configuration files in $dxs_conf # dhcp sed -e "s,@@@server@@@,${server},g;s,@@@netname@@@,${netname},g;s,@@@netmask@@@,${netmask},g;s,@@@broadcast@@@,${broadcast},g" default_files/dhcpd.conf > ${dxs_conf}/${dxs_dhcpd_conf}-${timestamp} # TODO: sed -e @@@example1@@@, netname+1 etc. - which ip addresses are safe to use? # atftpd sed -e "s,@@@tftpbootdir@@@,${tftpbootdir}," default_files/${atftpd_conf_name} > ${dxs_conf}/${dxs_atftpd_conf}-${timestamp} # nfs echo -e "# Bla Blub\n \ # NFS export entry for DXS\n\ ${rootdir} ${netname}/${netmask}(ro,no_root_squash,async)" >> ${dxs_conf}/${dxs_exports_conf}-${timestamp} # pxe [ -d ${tftpbootdir} ] || mkdir -p ${tftpbootdir} rsync -a --exclude=.svn default_files/tftpboot/* ${tftpbootdir} sed -e "s,@@@server@@@,${server},g;s,@@@tftpbootdir@@@,${tftpbootdir},g;s,@@@pxe_passwd@@@,${pxe_passwd},g;s,@@@client_distro@@@,${client_distro},g;s,@@@client_distro_ver@@@,${client_distro_ver},g;s,@@@rootdir@@@,${rootdir},g" default_files/default > ${dxs_conf}/${dxs_pxedefault_conf}-${timestamp} declare -i j=0 while [ $j -lt ${#choice[@]} ] ; do current_kernel=${kernel[$j]#${rootdir}/boot/vmlinuz-} current_initrd=${tftpbootdir}/initrd-dxs-${current_kernel} if [ $j -eq 0 ] ; then default_string=" MENU DEFAULT\n" else default_string="" fi echo -e "LABEL ${client_distro}-${current_kernel}\n${default_string} \ MENU LABEL $j. ${client_distro}-${client_distro_ver} ${current_kernel} Diskless\n \ KERNEL ${server}::${tftpbootdir}/vmlinuz-${current_kernel}\n \ APPEND nfsroot=${server}:${rootdir} initrd=${server}::${tftpbootdir}/initrd-dxs-${current_kernel} apic dhcp noldsc vci=DXS\n \ ipappend 1\n\n" >> ${dxs_conf}/${dxs_pxedefault_conf}-${timestamp} j=$j+1 done # backing up original files for cfile in \ ${dhcpd_conf} ${atftpd_conf} ${exports_conf} \ ${tftpbootdir}/${pxedefault_conf} ${client_conf} ; do if [ -f ${cfile} -a ! -L ${cfile} ] ; then echo "Copying old ${cfile} to ${cfile}.original" mv ${cfile} ${cfile}.original elif [ -L ${cfile} ] ; then unlink ${cfile} fi done # linking files for cfile in "${dxs_dhcpd_conf} ${dhcpd_conf}" "${dxs_atftpd_conf} ${atftpd_conf}" "${dxs_exports_conf} ${exports_conf}" "${dxs_pxedefault_conf} ${tftpbootdir}/${pxedefault_conf}" ; do set -- $cfile ln -s ${dxs_conf}/${1}-${timestamp} ${2} done } footer() { echo -e "\nPlease assure to restart atftpd, nfs-kernel-server and dhcpd!\n" echo -e "\nInstallation finished.\n" # TODO: tell user things he's got to configure afterwards - point to README # * in dhcpd.conf - put in clients mac and ip addresses # * make services start (automatically at server boot) } ## ------ MAIN ------ ## pxedefault_conf="pxelinux.cfg/default" dxs_conf="/etc/dxs/" dxs_dhcpd_conf="dhcp/dhcpd.conf" dxs_atftpd_conf="atftpd/atftpd" dxs_exports_conf="nfs/exports" dxs_pxedefault_conf="pxelinux/default" header precheck #(run as root, rsync etc.) configure copy_system create_initrd setup_server footer