#!/bin/bash
#
# mkdiskless is a script to configure the diskless NFS share.
#   It takes one parameter containing the name of the directory where the 
#   "root" directory of the diskless environment resides.
#   If you copied the Red Hat Enterprise Linux AS OS to 
#       /diskless/i386/RHELAS/root then you would run
#       mkdiskless /diskless/i386/RHELAS
#   This script can be run multiple times and should be run everytime you 
#   update the software on this share.
#
#   If this script has been run more than once for a client root installation,
#   then no configuration files will be modified unless the environment variable 
#   $FORCE_MKDISKLESS is set to a non-empty value.
#
# Copyright (C) 2003 Daniel Walsh <dwalsh@redhat.com> (Red Hat, Inc.)
# Copyright (C) 2005, 2006 Jason Vas Dias <jvdias@redhat.com> (Red Hat, Inc.)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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
#

if [ $# != 1 ]; then
        echo $"Usage: $0 DISKLESSDIRECTORY"
        exit 1
fi
INSTALLDIR=/usr/share/system-config-netboot/diskless
base=`basename $1`
if [ $base == "root" ]; then
    wd=`dirname $1`
else
    wd=$1
fi
ROOT=$wd/root
ROOT=`dirname $ROOT`/root
if [ ! -d $ROOT ]; then
        echo $"$wd must point to a directory containing a root subdirectory"
        exit 1
fi
SNAPSHOT=$wd/snapshot
#
# Create snapshot directory which will contain all client specific files.
#
mkdir -p $SNAPSHOT
#
#  Copy the file files to the snapshot directory.
#  This file contains a  list of the non-shared files/directories 
#   on to the diskless root directory
#  Everytime the client boots it checks this file.  
#      If the client's snapshot directory does not contain a file/directory c
#      contained in files, it will copy it from the root directory.
#  The client will mount -o bind all entries from the snapshot directory over 
#      The entries in the root directory, so that they can be written too.
#
cp -fp $INSTALLDIR/files $SNAPSHOT
#
#  Add the diskless service script.  Currently this script only unmounts the 
#  memory resident kernel used to boot the diskless client, and is only
#  required by initscripts < 7.62; initscripts >= 7.62 uses /etc/rc.readonly
#
if [ ! -e $ROOT/etc/init.d/diskless ] || [ -n "$FORCE_MKDISKLESS" ]; then
    cp -fp $INSTALLDIR/diskless.init $ROOT/etc/init.d/diskless;
    chmod 755 $ROOT/etc/init.d/diskless;
    ls $ROOT/etc/rc.d/rc*.d/[KS]*diskless &>/dev/null;
    if [ $? -ne 0 ] || [ -n "$FORCE_MKDISKLESS" ]; then
	(cd $ROOT/etc/rc3.d/; ln -sf ../init.d/diskless S01diskless);
	(cd $ROOT/etc/rc5.d/; ln -sf ../init.d/diskless S01diskless);
    fi;
fi;
if [ ! -e $ROOT/etc/rc.readonly ] || [ -n "$FORCE_MKDISKLESS" ]; then
   echo '#!/bin/bash
# rc.readonly:
#
# script for diskless initialization sourced by rc.sysinit
#
# Created by system-config-netboot mkdiskless script
#
# Unmount the initrd root left over from the diskless boot:
umount -f /.oldroot 2> /dev/NULL || :;
/sbin/blockdev --flushbufs /dev/ram0 2>/dev/null || :;
touch /var/lock/subsys/diskless
'  >  $ROOT/etc/rc.readonly ;
fi;
if [ ! -e $ROOT/etc/sysconfig/init.prediskless ] || [ -n "$FORCE_MKDISKLESS" ]; then
    cp -fp $ROOT/etc/sysconfig/init $ROOT/etc/sysconfig/init.prediskless 2>/dev/null || touch $ROOT/etc/sysconfig/init.prediskless;
###
#
#  Configure new "READONLY" rc.sysinit option to prevent remounting / RW:
#
    if ! egrep -q '^READONLY=' $ROOT/etc/sysconfig/init ; then
	echo 'READONLY=yes' >> $ROOT/etc/sysconfig/init ;
    fi
#
#  With old initscripts (RHL-8), prevent fsck failure for '/' rootfs device :-( 
#  / disable fsck checking at boot (since the clients are meant to be diskless!):
    if ! egrep -q '^fastboot=' $ROOT/etc/sysconfig/init; then
	echo 'fastboot=yes' >> $ROOT/etc/sysconfig/init ;
    fi;
fi
if [ ! -e $ROOT/etc/sysconfig/readonly-root ] || [ -n "$FORCE_MKDISKLESS" ]; then 
    echo '# configuration settings for systems with read-only root filesystems.
# sourced by rc.sysinit during boot.
# configured by system-config-netboot
# Settings:
#          READONLY=yes/no - yes: invoke rc.sysinit read-only root support
READONLY=yes
'   > $ROOT/etc/sysconfig/readonly-root;
fi
if ! egrep -q '^READONLY=' $ROOT/etc/sysconfig/readonly-root ; then
    echo 'READONLY=yes' >> $ROOT/etc/sysconfig/readonly-root ;
fi;
###
#
#  Replace the fstab with a generic fstab that contains no local disks.
#  ( allowing users to preserve modified diskless fstab files! )
# 
if [ ! -e $ROOT/etc/fstab.prediskless ] || [ -n "$FORCE_MKDISKLESS" ] ; then
   cp -fp $ROOT/etc/fstab $ROOT/etc/fstab.prediskless 2>/dev/null || touch $ROOT/etc/fstab.prediskless;
   echo '# /etc/fstab for diskless clients, written by system-config-netboot' > $ROOT/etc/fstab
   cat $INSTALLDIR/fstab >> $ROOT/etc/fstab
   chown root:root $ROOT/etc/fstab
   chmod 0644 $ROOT/etc/fstab
   touch -r $INSTALLDIR/fstab $ROOT/etc/fstab
fi;

###
#
#  Create the .snapshot directory in the root partition.  This will be used 
#  by the client as the mount point of the snapshot directory from the server.
#
mkdir -p $ROOT/.snapshot

mkdir -p $ROOT/proc
#
#  Create the .oldroot directory in the root partition.  This will be used 
#  by pivot-root to mount the memory resident root directory.  It is unmounted
#  by the diskless service script.
#
mkdir -p $ROOT/.oldroot

###
#
# This script will now remove all scripts that cause problems for the diskless
# environment
#
#echo cleaning up network scripts
#
# Since there is no disk autofsck is not used
#
rm -f $ROOT/.autofsck
if [ ! -e $ROOT/etc/lvmtab.prediskless ] || [ -n "$FORCE_MKDISKLESS" ]; then
#
# Since there is no disk lvm will not work
#
    cp -fp $ROOT/etc/lvmtab $ROOT/etc/lvmtab.prediskless 2>/dev/null || touch $ROOT/etc/lvmtab.prediskless;

    rm -f $ROOT/etc/lvmtab;
fi
#
#
if [ -n "$FORCE_MKDISKLESS" ] || ! [ -e $ROOT/etc/sysconfig/network.prediskless ]; then
    #
    # Since the network is brought up using the memory resident partition,
    # no network scripts are needed or used by default; 
    # but allow custom networking to be set up and this script to be re-run.
    #
    cp -fp $ROOT/etc/sysconfig/network $ROOT/etc/sysconfig/network.prediskless 2>/dev/null || touch $ROOT/etc/sysconfig/network.prediskless;
    rm -f $ROOT/etc/rc.d/rc*.d/K*network
    rm -f $ROOT/etc/rc.d/rc*.d/K*netfs
    for f in $ROOT/etc/sysconfig/network-scripts/ifcfg-eth*; do
	mv -f $f ${f/ifcfg-/prediskless-ifcfg-};
    done;
    if ! egrep -q '^keep_old_ip=' $ROOT/etc/sysconfig/network; then
    # prevent dhclient-script bringing down an interface before bringing it up!
    # permits dhclient to be re-run for the nfs root interface.
	echo 'keep_old_ip=yes' >> $ROOT/etc/sysconfig/network;
    fi;
    #
    # Eliminate the HOSTNAME entry from the /etc/sysconfig/network script.
    # This will be set by the memory resident boot environment
    #
    if egrep -q "^HOSTNAME" $ROOT/etc/sysconfig/network 2>/dev/null; then
	grep -v "^HOSTNAME" $ROOT/etc/sysconfig/network > /tmp/network;
	mv  -f /tmp/network $ROOT/etc/sysconfig/network;
    fi;
fi;

if [ ! -e $ROOT/etc/syslog.conf.prediskless ] || [ -n "$FORCE_MKDISKLESS" ] ; then
#
# Setup all logging to go to this server
# (but allow custom logging to be setup and this script to be re-run.)
    cp -fp $ROOT/etc/syslog.conf $ROOT/etc/syslog.conf.prediskless 2>/dev/null || touch  $ROOT/etc/syslog.conf.prediskless;
    echo -e "# syslog.conf maintained by system-config-netboot\n# If you wish to maintain your own syslog.conf, remove the above line\n\n*.*	@`hostname`" > $ROOT/etc/syslog.conf;
fi;
##
# Everytime software is installed RPM leaves the DB files around. The system
# startup scripts remove them on boot.  Since we are on a read/only file system
# attempting to remove these files creates an error on the screen.  Eliminating
# these files now eliminates this error.
#
rm -f $ROOT/var/lib/rpm/__db*

##
# Eliminate cron jobs that do not make sense on a Diskless environment.
# The server can run these jobs to update the man pages and locate database.
#
#echo removing makewhatis from cron
rm -f $ROOT/etc/cron.daily/makewhatis.cron
rm -f $ROOT/etc/cron.monthly/makewhatis.cron

#echo removing slocate from cron
rm -f $ROOT/etc/cron.daily/slocate.cron

#
# Create files that do not necessarily exist when the client is installed.
# If the client needs to change the XF86Config file it will need write access
# to this file.
#
[ ! -e $ROOT/etc/X11/XF86Config.backup ] &&  touch $ROOT/etc/X11/XF86Config.backup;
[ ! -e $ROOT/etc/X11/xorg.conf.backup ] && touch $ROOT/etc/X11/xorg.conf.backup;

#
# /proc is client specific.  Creating a link from /etc/mtab -> /proc/mounts
# eliminates alot of potential problems
#
# echo Creating mtab link
if [ ! -e $ROOT/etc/mtab.prediskless ] || [ -n "$FORCE_MKDISKLESS" ] ; then
    mv -f $ROOT/etc/mtab $ROOT/etc/mtab.prediskless 2>/dev/null || touch $ROOT/etc/mtab.prediskless;
    ln -s /proc/mounts $ROOT/etc/mtab
fi;
#
# Remove all lock,run,spool,log files that may have been left over from the
# initial client installation
#
rm -f `find $ROOT/var/lock -type f`
rm -f `find $ROOT/var/run -type f`
rm -rf $ROOT/var/tmp/*
rm -rf $ROOT/tmp/*

for i in `find $ROOT/var/spool -type f`; do
    cat /dev/null >> $i
done
for i in `find $ROOT/var/log -type f`; do
    cat /dev/null >> $i
done
#
#  Remove the host ssh keys so that each client will regenerate them:
if [ ! -e $ROOT/etc/ssh.prediskless ] || [ -n "$FORCE_MKDISKLESS" ]; then
   touch $ROOT/etc/ssh.prediskless;
   rm -f $ROOT/etc/ssh/ssh_host_*;
fi
#
#  We need to make small changes to the following startup scripts,
#  with initscripts < 7.62 (ie. RHEL-3 or before) :
#
#echo Applying Patches
#
#  These only work with initscripts <= 7-62 !
#
# rc.sysinit Changes
#  Stop rc.sysinit from trying to remount the / file systems rw.
#     / needs to stay r/o
#  Don't create /.autofsck since this is a diskless client
#
if [ ! -e $ROOT/etc/rc.d/rc.sysinit.prediskless ] || [ -n "$FORCE_MKDISKLESS" ]; then
    patch -N -b -z .prediskless    $ROOT/etc/rc.d/rc.sysinit ${INSTALLDIR}/rc.sysinit.patch >/dev/null 2>&1;
fi;
#
#  Halt changes
#    Don't unmount /dev directory since it is mounted using NFS
#    This would cause the halt to hang
#
if [ ! -e $ROOT/etc/init.d/halt.prediskless ] || [ -n "$FORCE_MKDISKLESS" ]; then
    patch -N -b -z .prediskless    $ROOT/etc/init.d/halt ${INSTALLDIR}/halt.patch >/dev/null  2>&1;
fi;
#
#  netfs changes
#    Don't unmount /.snapshot directory since it is mounted using NFS
#    This would cause the halt to hang
#
if [ ! -e $ROOT/etc/init.d/netfs.prediskless ] || [ -n "$FORCE_MKDISKLESS" ]; then
    patch -N -b -z .prediskless    $ROOT/etc/init.d/netfs ${INSTALLDIR}/netfs.patch >/dev/null 2>&1;
fi
#
#  xfs changes:
#     xfs does a whole lot of evil stuff to the /usr directory in order
#      to maintain protections.  This patch eliminates these changes
#
if [ ! -e $ROOT/etc/init.d/xfs.prediskless ] || [ -n "$FORCE_MKDISKLESS" ]; then
    patch -N -b -z .prediskless    $ROOT/etc/init.d/xfs ${INSTALLDIR}/xfs.patch >/dev/null 2>&1;
fi
#echo all done
#
# This used to be done, but is pointless since GUI requires these entries 
# in exports BEFORE mkdiskless is run.
# GUI should set these up for user ...
#if ! egrep -q $ROOT /etc/exports  > /dev/null 2>&1; then
#
#    echo "$ROOT *(ro,no_root_squash,sync)" >> /etc/exports ;    
#    echo "$SNAPSHOT *(rw,no_root_squash,sync)" >> /etc/exports ;
#    exportfs -r ;
#fi

exit 0
