#!/bin/bash
##
#  Korinf project
#
#  Local chroot mount related functions
#
#  Copyright (c) Etersoft <http://etersoft.ru> 2005, 2006, 2007, 2009
#  Copyright (c) Vitaly Lipatov <lav@etersoft.ru> 2009
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Affero General Public License as published by
#  the Free Software Foundation, either version 3 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 Affero General Public License for more details.

#  You should have received a copy of the GNU Affero General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
##


MOUNT_MODULE_INCLUDED=1

mount_linux()
{
	local dist=$1
	is_remote_build $dist && return
	local MOUNTPARAM

	# Note!
	BUILDERHOME=$2

	assert_var CHROOTDIR LOCUSER

	# x86_64/Debian/6.0 -> x86_64-Debian-6.0
	BUILDROOT=`mktemp -d $CHROOTDIR/${dist//\//-}-XXXXXX`
	# Создаём необходимые каталоги
	mkdir -p $CHROOTDIR
	$SUDO chown $LOCUSER $CHROOTDIR

	# Note! Define and create BUILDHOME here
	if [ -z "$BUILDERHOME" ] ; then
		# create temp home
		BUILDERHOME=$BUILDROOT-home
		mkdir -p $BUILDERHOME/{,tmp,RPM,RPM/BUILD,RPM/RPMS} || fatal "Can't create $BUILDERHOME"
		chmod g+rwx $BUILDERHOME
		$SUDO chown $LOCUSER $BUILDERHOME -R
	fi

	# FIXME: why LOCUSER??
	chmod g+rwx $BUILDROOT
	$SUDO chown $LOCUSER $BUILDROOT -R

	[ -z "$BUILDROOT" ] && echo "Skip mount due empty BUILDROOT" && return 1
	echo "Mount $LOCALLINUXFARM/$dist to $BUILDROOT (user $INTUSER)..."

	# FIXME:
	[ -d $LOCALLINUXFARM ] && MOUNTPARAM="--bind" || MOUNTPARAM="-o soft"
	$SUDO mount $LOCALLINUXFARM/$dist $BUILDROOT $MOUNTPARAM || { warning "Cannot mount..." ; return 1 ; }
	$SUDO chmod o+rx $BUILDROOT
	#ls -l $BUILDROOT
	test -d $BUILDROOT/etc/ || fatal "Linux system is missed in $BUILDROOT"

	# TODO: need create these dir as root!
	# $BUILDROOT/run
	$SUDO su $LOCUSER -c "mkdir -p $BUILDROOT/proc $BUILDROOT/sys $BUILDROOT/tmp $BUILDROOT/home $BUILDROOT/home/$INTUSER $BUILDROOT/srv/wine"
	$SUDO mount -t proc proc $BUILDROOT/proc || { warning "Cannot mount /proc" ; return 1 ; }
	$SUDO mount -t sysfs none $BUILDROOT/sys || { warning "Cannot mount /sys" ; return 1 ; }
	#$SUDO mount $BUILDROOT $BUILDROOT/sys || { warning "Cannot mount /sys" ; return 1 ; }
	$SUDO mount -t devpts none $BUILDROOT/dev/pts -o nosuid,noexec,gid=tty,mode=620 || { warning "Cannot mount /sys" ; return 1 ; }

	if [ -d "$BUILDROOT/dev/shm" ] ; then
		$SUDO mount -t tmpfs shmfs $BUILDROOT/dev/shm || { warning "Cannot mount /dev/shm" ; return 1 ; }
	fi

	echo "Mount home $BUILDERHOME ..."
	$SUDO mount $BUILDERHOME $BUILDROOT/home/$INTUSER --bind || { warning "Cannot mount home" ; return 1 ; }

	echo "Mount /tmp $BUILDROOT-tmp ..."
	mkdir -p $BUILDROOT-tmp
	# TODO: not allowed in sudo
	#$SUDO chown root:root $BUILDROOT-tmp
	$SUDO chmod 01777 $BUILDROOT-tmp
	$SUDO mount $BUILDROOT-tmp $BUILDROOT/tmp --bind || { warning "Cannot mount /tmp" ; return 1 ; }

	#echo Mount srv/wine...
	#$SUDO mount /net/wine $BUILD/srv/wine --bind || { warning "Cannot mount home" ; return 0 ; }
}

terminate_using()
{
	local u
	local LISTPROC
	u=$1
	$SUDO fuser -vk $u
	LISTPROC=`$SUDO su $LOCUSER -c "/usr/sbin/lsof | grep $u | awk '{print \\$2}' | sort -u"`
	echo "Kill process use our dir (f.i. gpg-agent): $LISTPROC"
	$SUDO su $LOCUSER -c "echo $LISTPROC | xargs kill"
}

end_umount()
{
	# if early error
	[ -z "$DISTRNAME" ] && return

	is_remote_build && return
	local i u ERR
	ERR=0
	if [ -z "$BUILDROOT" ] ; then
		[ -z "$ADEBUG" ] || echo "Skip umount due empty BUILDROOT"
		return 1
	fi

	echo "Unmounting and cleaning $BUILDROOT..."
	for i in /proc/bus/usb /proc/sys/fs/binfmt_misc /proc /sys /run /home/$INTUSER /dev/shm /dev/pts /tmp / ; do
		u=$BUILDROOT$i
		if [ -d $u ] && mount | grep $i >/dev/null ; then
			if ! $SUDO umount $u ; then
				terminate_using $u
				sleep 1
				$SUDO umount -v $u || terminate_using $u
			fi
			#|| echo "Failed $u umount"
			#$SUDO umount $i || $SUDO umount $i -l || ERR=1
		fi
	done
	[ $ERR = 0 ] && echo "DONE" || echo "Umount FAILED"
	if [ -z "$ADEBUG" ] ; then
		if echo $BUILDERHOME | grep -q $BUILDROOT ; then
			echo "Removing $BUILDERHOME ..."
			#$SUDO su $LOCUSER -c "rm -rf $BUILDERHOME" || ERR=1
			$SUDO su $LOCUSER -c "rm -rf $BUILDERHOME" || sleep 2 || $SUDO su $LOCUSER -c "rm -rf $BUILDERHOME" || (echo $(fuser $BUILDERHOME) && ERR=1)
			TMPBUILDERHOME=
		fi
		echo "Removing $BUILDROOT ..."
		#$SUDO su $LOCUSER -c "rmdir -v $BUILDROOT" || ERR=1
		$SUDO su $LOCUSER -c "rmdir -v $BUILDROOT" || sleep 2 || $SUDO su $LOCUSER -c "rmdir -v $BUILDROOT" || (echo $(fuser $BUILDERROOT) &&  ERR=1)
		[ $ERR = 0 ] && echo "DONE" || echo "Removing FAILED"
	else
		echo "Skip removing due ADEBUG set"
	fi
	BUILDROOT=""
	return $ERR
}

# use --user for change to local user INTUSER
run_in_chroot()
{
	assert_var DISTRNAME DISTRVERSION INTUSER

	local LOUSER=""
	if [ "$1" = "--user" ] ; then
		LOUSER=$INTUSER
		shift
	else
		# FIXME
		LOUSER=root
	fi

	# run via ssh if remote build system
	local rhost rcommands
	rhost=$(get_remote_host $DISTRNAME/$DISTRVERSION)
	if [ -n "$rhost" ] ; then
		rcommands=`eval echo $(get_remote_commands $DISTRNAME/$DISTRVERSION)`
		# do not use command for a user
		#[ -n "$LOUSER" ] || rcommands=
		# Note: this output can be write to file with redirect output
		echo "Run command in remote ($rhost) build system:" >&2
		echo "# $@" >&2
		# FIXME: add -t if need interactive
		if [ -z "$LOUSER" ] || [ "$LOUSER" = "root" ] ; then
		    #ssh -i $PRIVATESSHKEY $INTUSER@$rhost $rcommands "\"export LANG=C ; export LC_ALL=C ; $@\""
		    ssh -i $PRIVATESSHKEY $INTUSER@$rhost $rcommands "\"$@\""
		else
		    ssh -i $PRIVATESSHKEY $INTUSER@$rhost "export LANG=C ; export LC_ALL=C ; . ~/.profile ; $@"
		fi
		return
	fi

	echo "Run command in chrooted build system:" >&2
	echo "# $@" >&2
	assert_var BUILDARCH BUILDROOT
	$NICE setarch $BUILDARCH $SUDO chroot $BUILDROOT \
		su - $LOUSER -c "export LANG=C ; export LC_ALL=C ; $@"
}
