#!/bin/bash 
#
#M Build gentoo from scratch
#
# Bsp.
# cp /root/chroot.sh /mnt/gentoo/root/.bashrc 
# chroot /mnt/gentoo /bin/bash
#
config='/mnt/gentoo/gentoo-build/config'
TARGET=/mnt/gentoo
rootdisk=`mount | grep "on / type " | awk '{print $1}'`
#rootdisk=${rootdisk:5:4}
rootdisk="/dev/hda6"
bootdisk="/dev/hda2"
proxy=http://www-proxy.admin.ch:8080
userid='t759f'
clear
echo "========================================================="
echo "              Build gentoo from scratch "
echo " (C) COPYRIGHT Bruno Brueckmann 2008 "
echo "========================================================="
echo "Parameters for build:"
echo "Init Root-Disc ="$rootdisk
echo "Boot Partition ="$bootdisk
echo "Proxy          ="$proxy
echo "Target         ="$TARGET
echo "Configuration  ="$config
echo "Userid         ="$userid
echo "ACHTUNG ATTENTION ! run this script not in an active system, only in "
echo "a new virtual server"
echo "Start with this parameters y/n ?"
read input
if [ "$input" != "y" ]; then
 exit
fi
if [ -n "$proxy" ]; then
`export http_proxy="${proxy}"`
fi
mkdir ${TARGET}
mount $rootdisk ${TARGET}
mkdir ${TARGET}/boot
#mount /dev/hda2 ${TARGET}/boot
mkdir ${TARGET}/proc
mount -t proc none ${TARGET}/proc
mkdir ${TARGET}/dev
mount -o bind /dev ${TARGET}/dev
# download stage3 and portage
cwd=`pwd`
cd ${TARGET}
wget http://mirror.switch.ch/ftp/mirror/gentoo/releases/x86/current/stage3-i686-20090602.tar.bz2
if [ "$?" -ne "0" ]; then
 echo "error wget "
  exit 8
fi
wget http://distfiles.gentoo.org/snapshots/portage-latest.tar.bz2
if [ "$?" -ne "0" ]; then
 echo "error wget "
  exit 8
fi
# extract stage3 and portage
tar -xvjf stage3*
tar -xvjf portage* -C ${TARGET}/usr
cd ${cwd}
# define user-home
mkdir ${TARGET}/home/${userid}
#  build make.conf
mkdir ${TARGET}/etc/
cp ${config}/make.conf ${TARGET}/etc/make.conf
# build resolv.conf
cp ${config}/resolv.conf ${TARGET}/etc/resolv.conf
# build rc.conf
cp ${config}/rc.conf ${TARGET}/etc/rc.conf 
# build keymaps
cp ${config}/keymaps ${TARGET}/etc/conf.d/keymaps
# build fstab
cp ${config}/fstab ${TARGET}/etc/fstab
# build locale
cp ${config}/locale ${TARGET}/etc/locale.gen
# build dhcp
cp ${config}/dhcp ${TARGET}/etc/conf.d/dhcp
# build apache
cp ${config}/apache ${TARGET}/etc/conf.d/apache2
# build dhcrelay
cp ${config}/dhcrelay ${TARGET}/etc/conf.d/dhcrelay
# build gpm
cp ${config}/gpm ${TARGET}/etc/conf.d/gpm
# build ifplugd
cp ${config}/ifplugd ${TARGET}/etc/conf.d/ifplugd
# build usermounts
cp ${config}/usermounts ${TARGET}/etc/init.d/usermounts
# build group
cp ${config}/group ${TARGET}/etc/group
# build passwd
cp ${config}/passwd ${TARGET}/etc/passwd
# build shadow
cp ${config}/shadow ${TARGET}/etc/shadow
# build hosts
cp ${config}/hosts ${TARGET}/etc/hosts
# build sudoers
cp ${config}/sudoers ${TARGET}/etc/sudoers
# build net
cp ${config}/net ${TARGET}/etc/conf.d/net
# grub stage1
mkdir ${TARGET}/boot
mkdir ${TARGET}/boot/grub
cp -r ${config}/grub ${TARGET}/boot/grub
# build linux config
mkdir ${TARGET}/usr/src/
mkdir ${TARGET}/usr/src/linux/
cp ${config}/.config ${TARGET}/usr/src/linux/.config
# build firewall
cp ${config}/firewall ${TARGET}/etc/init.d/firewall
# build xorg
mkdir ${TARGET}/etc/X11/
cp ${config}/xorg.conf ${TARGET}/etc/X11/xorg.conf
# build cpkernel
cp ${config}/cpkernel ${TARGET}/cpkernel
# build vsftpd
mkdir ${TARGET}/etc/vsftpd
cp ${config}/vsftpd.conf ${TARGET}/etc/vsftpd/vsftpd.conf
# build hostname
echo 'HOSTNAME=bit3055-Site-A' >${TARGET}/etc/conf.d/hostname
cp /etc/cups/printer.conf ${TARGET}/etc/cups/printer.conf
cp /etc/cups/lpoptions ${TARGET}/etc/cups/lpoptions
#
# update profile
mkdir ${TARGET}/etc/profile
echo 'export http_proxy="http://www-proxy.admin.ch:8080"' >> ${TARGET}/etc/profile
echo 'export PATH="${PATH}:/usr/local/lib/R/bin:/usr/local/bin:/usr/local/lib"' >> ${TARGET}/etc/profile
echo 'export LANG="de_DE@euro"' >> ${TARGET}/etc/profile
# build grub
mkdir ${TARGET}/boot/grub
cp ${config}/menu.lst ${TARGET}/boot/grub/menu.lst
cp ${config}/grub.conf ${TARGET}/boot/grub/grub.conf
# build samba
mkdir ${TARGET}/etc/samba
cp ${config}/smb.conf ${TARGET}/etc/samba/smb.conf
# set user profiles
mkdir ${TARGET}/home/${userid}
cp ${config}/.x3270pro ${TARGET}/home/${userid}
# copy /dev/* to target
cp -r /dev/* ${TARGET}/dev
#
# wechseln in chroot
# Speichern der Kernel CMDLINE
mount -t proc none /mnt/gentoo/proc
mount -o bind /dev /mnt/gentoo/dev
CMDLINE=`cat /proc/cmdline`
#umount /proc
# prepare cmds running in chroot
mkdir ${TARGET}/root
cp ${config}/chroot-script ${TARGET}/chroot-script
chmod a+x ${TARGET}/chroot-script
cd ${TARGET}
# prepare some comds for chroot
#mkdir ${TARGET}/bin
#mkdir ${TARGET}/lib
#cp -a /bin/bash ${TARGET}/bin/bash
#cp -a /lib/libncurses.so.5 ${TARGET}/lib
#cp -a /lib/libdl.so.2 ${TARGET}/lib
#cp -a /lib/libc.so.6 ${TARGET}/lib
#cp -a /lib/ld-linux.so.2 ${TARGET}/lib
#cp -a /bin/ls ${TARGET}/bin/ls
#cp -a /lib/libcrypt.so.1 ${TARGET}/lib
#cp -a /lib/libm.so.6 ${TARGET}/lib
#cp -a /lib/libc.so.6 ${TARGET}/lib
#cp -a /lib/ld-linux.so.2 ${TARGET}/lib
exec chroot . /chroot-script >dev/console 2>&1
#
exit
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
linuxrc=$(cat <<!EOF
#!/bin/sh
export PATH=/bin

# Speichern der Kernel CMDLINE
mount -t proc none /proc
CMDLINE=`cat /proc/cmdline`
umount /proc

# CD Laufwerk mounten
CDROM=""
for x in hda hdb hdc hdd cdroms/cdrom0 cdroms/cdrom1 cdroms/cdrom2 cdroms/cdrom3 
do
  mount -t iso9660 -r /dev/${x} /cdrom > /dev/null 2>&1
  if [ "$?" = "0" ]
  then
    CDROM="${x}"
    break
  fi
done

# CD-Laufwerk nicht gefunden
if [ "${CDROM}" == "" ]
then
  exec /bin/sh
  exit
fi

# Wurzelverzeichnis mounten und Verzeichnisse mit Lese- und Schreibzugriff erstellen
mount -t squashfs -o loop /cdrom/files/source.img /new > /dev/null 2>&1
mount -t tmpfs -o size=8m none /new/var > /dev/null 2>&1
mount -t tmpfs -o size=4m none /new/etc > /dev/null 2>&1
mount -t tmpfs -o size=32m none /new/tmp > /dev/null 2>&1
mount -t tmpfs -o size=32m none /new/root > /dev/null 2>&1
cd /new/var && tar xpf /cdrom/files/var.tar > /dev/null 2>&1
cd /new/etc && tar xpf /cdrom/files/etc.tar > /dev/null 2>&1
cd /new/root && tar xpf /cdrom/files/root.tar > /dev/null 2>&1

# Wurzelverzeichnis umsetzen und den eigentlichen init-Vorgang starten
cd /new
pivot_root . newroot
exec chroot . /bin/sh <<- EOF1 >dev/console 2>&1
exec /sbin/init ${CMDLINE}
EOF1
!EOF)
echo "$linuxrc" > ${SOURCE}/linuxrc
chmod +x ${SOURCE}/linuxrc
#
fstype=$(cat <<!EOF
'
#!/bin/bash
# fstype partition|disk
# returns file system type to stdout
# (C) Klaus Knopper April 2004
# License: GNU GENERAL PUBLIC LICENSE version 2.0
# changed by flabra@carramba.homelinux.org

if [ -n "$1" ]; then
# Check if partition is already mounted
 while read device mountpoint filesystem relax; do
  case "$device" in 
    *$1*) [ "$device" = "$1" ] && { echo "$filesystem" ; exit 0 ; } ;;
  esac
  done <<EOT

checkswap(){
# Check for valid swap partition type
[ -n "$1" ] || return 1
while read device relax; do
case "$device" in $1) case "$relax" in *[Ss][Ww][Aa][Pp]*) return 0;; esac;; esac
done <<EOT
$(LANG=C LC_ALL=C LC_MESSAGES=C fdisk -l "${1%%[0-9]*}" 2>/dev/null)
EOT
return 1
}

# Check if a device/medium is present at all
 dd if="$1" count=1 bs=1k >/dev/null 2>&1 || exit 2
 FILE="$(LANG=C LC_ALL=C LC_MESSAGES=C file -Lkbs "$1")"
#debug code  LANG=C LC_ALL=C LC_MESSAGES=C file -Lkbs "$1"
 [ "$?" = "0" ] || exit 3
 if [ "$FILE" = "data" ]; then
 # could still be ReiserFS, since "file" only reads 64k in Debian
   FILE="$(dd if="$1" skip=16397 ibs=4 count=2 2>/dev/null)"
 fi
 case "$FILE" in
  *[Rr][Ee][Ii][Ss][Ee][Rr]*)  echo "reiserfs";;
  *ISO\ 9660*)                 echo "iso9660";;
  *[Mm][Ii][Nn][Ii][Xx]*)      echo "minix";;
  *[Xx][Ff][Ss]*)              echo "xfs";;
  *[Jj][Ff][Ss]*)              echo "jfs";;
  *[Ee][Xx][Tt]3*)             echo "ext3";;
  *[Ee][Xx][Tt]2*)             echo "ext2";;
  *[Ss][Ww][Aa][Pp]*)          checkswap "$1" && echo "swap" || echo "auto";;
  *[Nn][Tt][Ff][Ss]*)          echo "ntfs";;
  *[Ff][Aa][Tt]*)              echo "vfat";;
  *)                           echo "unknown";;
 esac
else
 echo "Usage: $0 partition|disk" >&2
 echo "   returns \"partition fstype\" lines to stdout." >&2
 exit 1
fi

exit 0
'
!EOF)
echo "$fstype" > ${SOURCE}/fstype
sed -e "s/'//g" ${SOURCE}/fstype >${SOURCE}/fstype1;rm ${SOURCE}/fstype;mv ${SOURCE}/fstype1 ${SOURCE}/fstype 
chmod +x ${SOURCE}/fstype

#
rebuildfstab=$(cat <<!EOF
'
#!/bin/bash
# (C) Klaus Knopper Nov 2002
# Calls scanpartitions as root and adds entries to /etc/fstab
# adapted by flabra <flabra@carramba.homelinux.org>

PATH="/bin:/sbin:/usr/bin:/usr/sbin;."
export PATH
umask 022

# make backup of fstab
[ ! -e /etc/fstab.orig ] && cp /etc/fstab /etc/fstab.orig

# create mountdir for all detected mountpoints
[ -d /mnt/dynamic ] && mkdir /mnt/dynamic 2>/dev/null

cp -f /etc/fstab.orig /etc/fstab
for i in /mnt/dynamic/* ; do rm -rf $i ; done

[ ! -e /proc/partitions ] && { echo "$0: /proc not mounted, exiting" >&2; exit 1; }

if [ -e /var/run/rebuildfstab.pid ]; then
 ps "$(</var/run/rebuildfstab.pid)" >/dev/null 2>&1 && exit 0
 rm -f /var/run/rebuildfstab.pid
fi

echo "$$" >/var/run/rebuildfstab.pid

TMP="/tmp/fstab.$$.tmp"
ADDEDBYKNOPPIX="# Added during startup"

# Simple shell grep, searches for lines STARTING with string
stringinfile(){
while read line; do
case "$line" in $1*) return 0;; esac
done <"$2"
return 1
}

echo "Scanning for new harddisks/partitions..." >&2
rm -f "$TMP"

cat /etc/fstab > "$TMP"

count=0
while read device mountpoint fstype relax; do
 # stringinfile "$device " "$TMP" || \
 stringinfile "$device " "/proc/mounts" || \
 { count="$((count + 1))"
   options="noauto,users,exec"
   case "$fstype" in
    ntfs) options="${options},ro,umask=077,uid=500,iocharset=iso8859-2,codepage=852" ;;
    vfat|msdos) options="${options},umask=077,uid=500,iocharset=iso8859-2,codepage=852" ;;
    swap) options="defaults" ;;
   esac
   [ -d "$mountpoint" ] || mkdir -p "$mountpoint" 2>/dev/null
   echo "$ADDEDBYKNOPPIX"
   echo "$device $mountpoint $fstype $options 0 0"
 }
done >>"$TMP" <<EOT
$(./scanpartitions)
EOT

[ "$count" -gt 0 ] && echo "Adding $count new partitions to /etc/fstab." >&2 || echo "No new partitions found." >&2;
mv -f "$TMP" /etc/fstab

rm -f /var/run/rebuildfstab.pid

[ -n "$DISPLAY" ] && sleep 2

exit 0
'
!EOF)
echo "$rebuildfstab" > ${SOURCE}/rebuildfstab
sed -e "s/'//g" ${SOURCE}/rebuildfstab >${SOURCE}/rebuildfstab1;rm ${SOURCE}/rebuildfstab;mv ${SOURCE}/rebuildfstab1 ${SOURCE}/rebuildfstab 
chmod +x ${SOURCE}/rebuildfstab
#
scanpartitions=$(cat <<!EOF
'
#!/bin/bash
# (C) Klaus Knopper Nov 2002
# Reads /proc/partitions, returns table of the form
# basename(devicefile) mountpoint filesystemtype
# Useful for automatic generation of /etc/fstab entries (you
# still may have to add noauto 0 0).

[ ! -e /proc/partitions ] && { echo "$0: /proc not mounted, exiting" >&2; exit 1; }

###

if [ -z "$1" ]; then
partitions=""
disks=""
disksize=0
blocksum=0
pold="none"
while read major minor blocks partition relax; do
partition="${partition#/dev/}"
[ -z "$partition" -o ! -e "/dev/$partition" ] && continue
[ "$blocks" -lt 2 ] 2>/dev/null && continue
case "$partition" in
?d?|ub?|ataraid/d?|rd/c?d?) disks="$disks $partition"; disksize="$blocks"; blocksum=0;;
ram*|cloop*|loop*) ;; # Kernel 2.6 bug?
*) blocksum="@(($blocksum + $blocks))"; [ "$blocksum" -gt "$disksize" ] >/dev/null 2>&1 || partitions="$partitions /dev/$partition";;
esac
done <<EOT
$(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
EOT

# Add disks without partition table (probably ZIP drives)
for d in $disks; do
case "$partitions" in */dev/$d*) continue;; esac
partitions="$partitions /dev/$d"
done
else
partitions="$*"
fi

for p in $partitions; do
fs="auto"
# fstype is an external script
scanfs="$(./fstype $p)"
[ -n "$scanfs" ] && fs="$scanfs"
mountpoint="/mnt/dynamic/${p##*/}"
[ "$fs" = "swap" ] && mountpoint="none"
echo "${p}" "${mountpoint}" "${fs}"
done

exit 0
'
!EOF)
echo "$scanpartitions" > ${SOURCE}/scanpartitions
# correct changes strings to prevent interpret
sed -e "s/'//g" ${SOURCE}/scanpartitions >${SOURCE}/scanpartitions1;rm ${SOURCE}/scanpartitions;mv ${SOURCE}/scanpartitions1 ${SOURCE}/scanpartitions 
sed -e "s/@((/\$((/g" ${SOURCE}/scanpartitions >${SOURCE}/scanpartitions1;rm ${SOURCE}/scanpartitions;mv ${SOURCE}/scanpartitions1 ${SOURCE}/scanpartitions 
chmod +x ${SOURCE}/scanpartitions


# end modifiy

cp -a ${SOURCE}/boot ${TARGET}/
mkdir -p ${TARGET}/files/source
#make sure the menu.lst is up to date (ONLY EDIT grub.conf!!)
#mkdir ${SOURCE}/boot/
mkdir ${SOURCE}/boot/grub
rm ${SOURCE}/boot/grub/menu.lst
grub=$(cat <<!EOF
default 0
timeout 30
splashimage=/boot/grub/splash.xpm.gz

title=LiveCD
kernel (cd)/boot/bzImage root=/dev/ram0 real_root=/dev/loop0 vga=0F00 looptype=squashfs loop=/livecd.squashfs udev nodevfs cdroot dodmraid 
initrd (cd)/boot/initramfs

title=LiveCD NO-FB
kernel (cd)/boot/bzImage root=/dev/ram0 real_root=/dev/loop0 looptype=squashfs loop=/livecd.squashfs udev nodevfs cdroot dodmraid
initrd (cd)/boot/initramfs

title=Memtest86+
kernel /boot/memtest86plus/memtest.bin
!EOF)
echo "$grub" >${SOURCE}/boot/grub/grub.conf
cp ${SOURCE}/boot/grub/grub.conf ${SOURCE}/boot/grub/menu.lst

mkdir -p ${SOURCE}/proc
mkdir -p ${SOURCE}/dev 
mkdir -p ${SOURCE}/sys
mkdir -p ${SOURCE}/boot
mkdir -p ${SOURCE}/usr/portage
mkdir -p ${SOURCE}/usr/portage/distfiles
mount -o bind /sys ${SOURCE}/sys
mount -o bind /dev ${SOURCE}/dev
mount -o bind /proc ${SOURCE}/proc
mount -o bind /usr/portage ${SOURCE}/usr/portage
mount -o bind /usr/portage/distfiles ${SOURCE}/usr/portage/distfiles

chroot ${SOURCE} /bin/bash --login <<CHROOTED
env-update
source /etc/profile
/sbin/depscan.sh
#modules-update
echo "sys-fs/dmraid ~x86" >> /etc/portage/package.keywords
echo "=sys-fs/dmraid-1.0.0_rc8-r1" >> /etc/portage/package.unmask
emerge memtest86+ localepurge gentoolkit dmraid livecd-tools mingetty
localepurge
makewhatis -u
make /etc/locale.gen list
emerge mkinitrd
emerge util-linux
emerge module-init-tools
emerge genkernel
#emerge gentoo-sources
cd /usr/src/linux
CHROOTED
cd ${SOURCE}
umount ${SOURCE}/sys
umount ${SOURCE}/dev
umount ${SOURCE}/proc
umount ${SOURCE}/usr/portage
umount ${SOURCE}/usr/portage/distfiles
env-update
source /etc/profile
