#!/usr/bin/env bash
## OpenVZ container-type virtualization installation functions.
## 
## Copyright 2012 Sergey Podushkin <psv AT tncc.ru>
## 
## 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., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301  USA
## 

PROFILE_NAME=$1
KICKSTART_URL=$2
ROOTDIR=$3
if [ -z "$PROFILE_NAME" -o -z "$ROOTDIR" -o -z "$KICKSTART_URL" ] ; then
    echo "Some arguments missing!"
    echo "Usage: $0 system_name kickstart_url private_dir"
    echo "Exiting..."
    exit 1
fi

PATH=/bin:/sbin:/usr/bin:/usr/sbin

KICKSTART="/tmp/$PROFILE_NAME-kickstart.cfg"
# get the kickstart
curl $KICKSTART_URL -s -o $KICKSTART

# get the root password hash from kickstart
ROOTPW=`cat $KICKSTART| awk '/^rootpw/{ print $NF }'`

# what shell will be used for post-install script? get it from kickstart
POST_INSTALL_SHELL=`cat $KICKSTART | grep '^%post.*--interpreter' | sed -n 's/^.*--interpreter \([^ ][^ ]*\).*/\1/;p'`
# if not defined in kickstart, then use /bin/sh
[ -z $POST_INSTALL_SHELL ] && POST_INSTALL_SHELL="/bin/sh"
# where to store post-install script
POST_INSTALL_SCRIPT="/tmp/$PROFILE_NAME-post-install"
# add postinstall script from kickstart
cat $KICKSTART | sed -n '0,/\%post/d;p' >$POST_INSTALL_SCRIPT

# get list of services that should be enabled after installation (anaconda-like behaviour)
SERVICES_ENABLED=`cat $KICKSTART| grep '^services.*--enabled' | sed 's/^services.*--enabled//; s/,/ /g'`
# get list of services that should be disabled after installation (anaconda-like behaviour)
SERVICES_DISABLED=`cat $KICKSTART| grep '^services.*--disabled' | sed 's/^services.*--disabled//; s/,/ /g'`
# some our anaconda-like actions before postinstall script execution
SERVICES_SCRIPT="/tmp/$PROFILE_NAME-services.sh"
cat /dev/null >$SERVICES_SCRIPT
# disable+enable service as directed in kickstart options
# first disable services
for serv in $SERVICES_DISABLED ; do
	echo chkconfig --level 345 $serv off >>$SERVICES_SCRIPT
done
# then enable services
for serv in $SERVICES_ENABLED ; do
	echo chkconfig --level 345 $serv on >>$SERVICES_SCRIPT
done

# temporary yum config
YUM_CONFIG="/tmp/$PROFILE_NAME-yum.cfg"
echo -e "[main]\ncachedir=/var/cache/yum/\$basearch/\$releasever\nkeepcache=0\ndebuglevel=2\nlogfile=/var/log/yum.log\nexactarch=1\nobsoletes=1\ngpgcheck=0\nplugins=1\ndistroverpkg=centos-release\nreposdir=/dev/null\n" >$YUM_CONFIG 
echo -e "groupremove_leaf_only=1\ngroup_package_types=mandatory\ntsflags=nodocs\n" >>$YUM_CONFIG

# --ignoremissing processing
cat $KICKSTART| grep '\-\-ignoremissing'>/dev/null
if [ $? -eq 0 ] ; then echo -e "skip_broken=1\n" >>$YUM_CONFIG ; fi

# just new line
echo >>$YUM_CONFIG

# base package set we get from kickstart's url option (this option used only for http/ftp install, that is in use by cobbler, if kickstart use other method we'll FAIL!!!)
BASE_REPO_URL=`cat $KICKSTART| grep ^url | sed 's/^url.*--url=//'`
# put in to our config
echo -e "[base-os]\nname=base-os\nbaseurl=$BASE_REPO_URL\nenabled=1\npriority=1\ngpgcheck=0\n\n" >>$YUM_CONFIG
# get additional repos from kickstart and put it to config too
cat $KICKSTART | grep ^repo | \
	sed 's/^repo\ //; s/--//g' | \
	while read repo_name repo_url ; do 
		repo_tag=`echo $repo_name | sed 's/name=//'`
		echo -e "[$repo_tag]\n$repo_name\n$repo_url\nenabled=1\npriority=99\ngpgcheck=0\n" >>$YUM_CONFIG
	done

# packages we don't need to install (but included in installed groups)
EXCLUDED_PKGS="selinux-policy-targeted kernel* *firmware* b43*"

# packages we want to be installed, besides of listed in kickstart
PKGS_LIST="vim-minimal ssh-clients openssh-server logrotate"

# temporary yum script
YUM_SCRIPT="/tmp/$PROFILE_NAME-yum.yum"
cp /dev/null $YUM_SCRIPT
(echo config assumeyes True
echo config gpgcheck False
echo install $PKGS_LIST
) >>$YUM_SCRIPT

if [ -n "$EXCLUDED_PKGS" ] ; then echo config exclude \"$EXCLUDED_PKGS\" >>$YUM_SCRIPT ; fi

cat $KICKSTART| awk '/^\%packages/,/^\%post/{ print $0 }'|egrep -v '^#|^$|^%' | \
while read line ; do
    # if package name can start with '-' sign, that means we have to exclude it
    ACTION="install"
    IS_GROUP=""
    echo $line|grep '^-'>/dev/null
    if [ $? -eq 0 ] ; then
        line=`echo $line|sed 's/^-//'`
        ACTION="remove"
    fi
    echo $line|grep '^@' >/dev/null
    # if name starts with @ - it's a group
    if [ $? -eq 0 ] ; then
        line=`echo $line|sed 's/^@//'`
        IS_GROUP="group"
    fi
    line=`echo $line | sed 's/^\s*//'`
    echo ${IS_GROUP}${ACTION} \"$line\" >>$YUM_SCRIPT
done

cat $KICKSTART| grep '\-\-nobase'>/dev/null
if [ $? -eq 0 ] ; then echo groupremove base >>$YUM_SCRIPT ; fi
echo run >>$YUM_SCRIPT

# install all packages in one pass by using yum shell
#### THIS IS LONG-RUNNING TASK! ######
echo Start installing packages
yum shell --quiet --config=$YUM_CONFIG --installroot=$ROOTDIR $YUM_SCRIPT
## >/dev/null 2>&1

# some optimization
yum remove kernel kernel-firmware dracut dracut-kernel dracut-network fcoe-utils libdrm lldpad plymouth -y --quiet --config=$YUM_CONFIG --installroot=$ROOTDIR
echo Packages installed


# remove all *.repo files, cobbler will install it's own repo-file with needed repos
rm -f $ROOTDIR/etc/yum.repos.d/*.repo

# move services setup script in container root, to be reachable inside of chroot
mv $SERVICES_SCRIPT $ROOTDIR/$SERVICES_SCRIPT
# turn off and on services in chroot
echo Disabling and enabling services as needed
chroot $ROOTDIR /bin/bash $SERVICES_SCRIPT

# move postinstall script in container root, to be reachable inside of chroot
mv $POST_INSTALL_SCRIPT $ROOTDIR/$POST_INSTALL_SCRIPT
# run the postinstall actions in chroot
echo Perform post-installation actions
(chroot $ROOTDIR $POST_INSTALL_SHELL $POST_INSTALL_SCRIPT )>/dev/null 2>&1

# tune the installations to be suitable for OpenVZ as environment
echo Make the tree container-ready
cd $ROOTDIR
# remove unneeded upstart scripts
rm -f $ROOTDIR/etc/init/control-alt-delete.conf
rm -f $ROOTDIR/etc/init/plymouth-shutdown.conf
rm -f $ROOTDIR/etc/init/prefdm.conf
rm -f $ROOTDIR/etc/init/quit-plymouth.conf
rm -f $ROOTDIR/etc/init/rcS-sulogin.conf
rm -f $ROOTDIR/etc/init/serial.conf
rm -f $ROOTDIR/etc/init/start-ttys.conf
rm -f $ROOTDIR/etc/init/tty.conf
sed -i -e 's/^console/#console/' $ROOTDIR/etc/init/rc.conf
sed -i -e 's/^console/#console/' $ROOTDIR/etc/init/rcS.conf

# tune sshd
sed -i -e 's/GSSAPIAuthentication\ yes/GSSAPIAuthentication\ no/g' $ROOTDIR/etc/ssh/sshd_config
# turn off SELinux
mkdir -p $ROOTDIR/etc/selinux
echo SELINUX=disabled>$ROOTDIR/etc/selinux/config

# we use ! as the delimiter for sed, because $ROOTPW hash is full of weird signs ;)
sed -i -e "s!root:.:!root:$ROOTPW:!" $ROOTDIR/etc/shadow

# who needs it?!
#echo "PS1='[\u@\h \W]\$'" >> /etc/profile

# link mtab from outer space
[ -f $ROOTDIR/etc/mtab ] && rm $ROOTDIR/etc/mtab
ln -s /proc/mounts etc/mtab

# some point to fstab
echo "none  /dev/pts    devpts  rw,gid=5,mode=620   0   0">$ROOTDIR/etc/fstab

# here is plain file dev/null, so we remove it
rm -f $ROOTDIR/dev/null
# create neccessary device files
for dir in $ROOTDIR/dev $ROOTDIR/etc/udev/devices ; do
    /sbin/MAKEDEV -d $dir -x {p,t}ty{a,p}{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f} console core full kmem kmsg mem null port ptmx random urandom zero ram0
    ln -s /proc/self/fd $dir/fd
    ln -s /proc/self/fd/2 $dir/stderr
    ln -s /proc/self/fd/0 $dir/stdin
    ln -s /proc/self/fd/1 $dir/stdout
done 

# ajust permissions
chmod 1777 $ROOTDIR/tmp
chmod 1777 $ROOTDIR/var/tmp

echo All done
exit 0
