#!/bin/sh -ef
#
# $Id: initroot,v 1.85 2005/10/09 19:58:38 ldv Exp $
# Copyright (C) 2003-2005  Dmitry V. Levin <ldv@altlinux.org>
# 
# The initroot utility for the hasher project
#
# This file 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
#

if [ "$0" = ./initroot ]; then
	. ./functions
	hasher_dir="$(/bin/pwd)"
else
	. /usr/share/hasher/functions
fi

show_help()
{
	cat <<EOF
initroot - fill hasher chroot with initial set of packages.

Usage: $PROG [options] <path-to-workdir>

<path-to-workdir> must be valid hasher directory.

Valid options are:
  --excludedocs                 do not install documentation files;
  --hasher-priv-dir=DIR         hasher-priv directory;
  --install-langs=LIST          colon-separated list of languages to install;
  --no-cache                    do not use cache;
  --no-contents-indices         do not use content indices;
  --no-repackage-source         do not repackage source along with binaries;
  --nprocs=NUMBER               number of CPUs to use;
  --number=NUMBER               subconfig identifier;
  --pkg-build-list=LIST         override default build package file list;
  --pkg-init-list=LIST          override default initial package file list;
  --pkg-noinstall-pattern-list  override default noinstall package pattern list;
  --repackage-source            repackage source along with binaries;
  --save-fakeroot               save fakeroot state;
  -q, --quiet                   try to be more quiet;
  -v, --verbose                 print a message for each action;
  -V, --version                 print program version and exit;
  -h, --help                    show this text and exit.
    
Report bugs to http://bugs.altlinux.ru/

EOF
	exit
}

TEMP=`getopt -n $PROG -o h,q,v,V -l contents-index-all:,contents-index-bin:,excludedocs,hasher-priv-dir:,install-langs:,no-cache,no-contents-indices,no-repackage-source,nprocs:,number:,pkg-build-list:,pkg-init-list:,repackage-source,save-fakeroot,help,quiet,verbose,version -- "$@"` ||
	show_usage
eval set -- "$TEMP"

build_list='basesystem rpm-build>=0:4.0.4-alt21 kernel-headers-common>=0:1.1.4-alt1 sisyphus_check>=0:0.7.3 time'
init_list='setup filesystem rpm fakeroot>=0:0.7.3'
noinstall_pattern_list='dev[-_][0-9]*'
install_langs=all
no_cache=
no_contents_indices=
nprocs=
repackage_source=1
while :; do
	case "$1" in
		--excludedocs) exclude_docs=--excludedocs
			;;
		--hasher-priv-dir)
			hasher_priv_dir="$(opt_check_dir "$1" "$2")"
			shift
			;;
		--install-langs) shift; install_langs="$1"
			;;
		--no-cache) no_cache=1
			;;
		--no-contents-indices) no_contents_indices=1
			;;
		--no-repackage-source) repackage_source=
			;;
		--nprocs)
			nprocs="$(opt_check_number "$1" "$2")"
			shift
			;;
		--number)
			number="$(opt_check_number "$1" "$2")"
			shift
			;;
		--pkg-build-list) shift; build_list="$1"
			;;
		--pkg-init-list) shift; init_list="$1"
			;;
		--pkg-noinstall-pattern-list) shift; noinstall_pattern_list="$1"
			;;
		--repackage-source) repackage_source=1
			;;
		--save-fakeroot) save_fakeroot=1
			;;
		--contents-index-*)
			Info "Warning: obsolete option $1 ignored."
			shift
			;;
		--) shift; break
			;;
		*) parse_common_options initroot "$1"
			;;
	esac
	shift
done

# Exactly one argument, please.
[ "$#" -ge 1 ] || show_usage 'Insufficient arguments.'
[ "$#" -le 1 ] || show_usage 'Too many arguments.'

set_workdir "$1"
shift

[ -d "$chroot" ] || Fatal "$chroot: cannot access chroot."
[ -d "$aptbox" ] || Fatal "$aptbox: cannot access aptbox."
[ -r "$APT_CONFIG" ] || Fatal "$APT_CONFIG: cannot access APT configuration."

if [ -n "$save_fakeroot" ]; then
	init_list="$init_list cpio"
fi

mkdir -p -m700 $verbose cache
rm -rf $verbose \
	cache/chroot/{list,package}.new cache/contents/{list,index}.new
mkdir -p -m700 $verbose cache/chroot/{list,package}{,.new}
mkdir -p -m700 $verbose cache/contents/{list,index}{,.new}

check_helpers

uid0="$(id -u)"
gid0="$(id -g)"

ugid1="$("$getugid1" ${number:+-$number})" ||
	Fatal 'getugid1 failed.'
uid1="$(printf %s "$ugid1" |cut -d: -f1)"
gid1="$(printf %s "$ugid1" |cut -d: -f2)"

ugid2="$("$getugid2" ${number:+-$number})" ||
	Fatal 'getugid2 failed.'
uid2="$(printf %s "$ugid2" |cut -d: -f1)"
gid2="$(printf %s "$ugid2" |cut -d: -f2)"

[ -n "$nprocs" ] ||
	nprocs="$(N=`egrep -cs ^cpu[0-9]+ /proc/stat ||:`; [ "$N" -gt 0 ] 2>/dev/null && printf %s "$N" || echo 1)"

check_tty

. "$hasher_dir/cache_chroot"
. "$hasher_dir/cache_contents"

init_list=`printf %s "$init_list" |tr -s ',[:space:]' ' ' |sed -e 's/^ \+//;s/ \+$//'`
[ -n "$init_list" ] ||
	Fatal 'Initial package file list is empty, cannot setup chroot.'

initlist="$(print_uris $init_list)" ||
	Fatal 'Failed to generate initial package file list.'
[ -n "$initlist" ] &&
	Verbose 'Generated initial package file list.' ||
	Fatal 'Failed to generate non-empty initial package file list; check your sources.list'

# reorder to get setup and filesystem first.
initlist="$(printf %s "$initlist" |grep '/setup[-_]' ||:)
$(printf %s "$initlist" |grep '/filesystem[-_]' ||:)
$(printf %s "$initlist" |egrep -v '/(setup|filesystem)[-_]' ||:)"
initlist="$(printf %s "$initlist" |grep -v '^$' ||:)"

if [ -z "$no_cache" ]; then
	printf %s "$initlist" >cache/chroot/list.new/init
	[ ! -s cache/chroot/list.new/init ] || echo >>cache/chroot/list.new/init
fi

build_list=`printf %s "$build_list" |tr -s ',[:space:]' ' ' |sed -e 's/^ \+//;s/ \+$//'`
if [ -n "$build_list" ]; then
	buildlist="$(print_uris $build_list)" ||
		Fatal 'Failed to generate build package file list.'
	buildlist="$(
		printf %s\\n "$buildlist" |while read bp; do
			[ -n "$bp" ] || continue
			printf %s "$initlist" |grep -qs "^$bp\$" || printf %s\\n "$bp"
		done
	)"
	buildlist="$(printf %s "$buildlist" |grep -v '^$' ||:)"
	[ -n "$buildlist" ] &&
		Verbose 'Generated build package file list.' ||
		Fatal 'Failed to generate non-empty build package file list; check your sources.list'
else
	Verbose 'Package file list for build is empty, bypassing.'
	buildlist=
fi # $build_list

if [ -z "$no_cache" ]; then
	printf %s "$buildlist" >cache/chroot/list.new/build
	[ ! -s cache/chroot/list.new/build ] || echo >>cache/chroot/list.new/build
fi

check_chroot_cache

if [ -n "$no_cache" -o -n "$rebuild_chroot_cache" ]; then
	create_chroot
else
	unpack_chroot_cache
fi

# Prepare /proc and /sys for potential mount.
rmdir $verbose chroot/proc chroot/sys &&
mkdir -m755 $verbose chroot/proc chroot/sys &&
chgrp "$gid1" $verbose chroot/proc chroot/sys &&
	Verbose 'Prepared mount points.' ||
	Fatal 'Failed to prepare mount points.'

check_contents_cache

if [ -n "$no_cache" -o -n "$rebuild_contents_cache" ]; then
	create_contents
else
	unpack_contents_cache
fi

if [ -n "$build_list" ]; then
	# Create /dev/log.
	/usr/bin/mksock -m666 "$chroot/dev/log" ||
		Fatal "Failed to create \`$chroot/dev/log' socket."

	# Create RPM build directory tree.
	create_entry_header
	cat >>"$entry" <<__EOF__
[ ! -d /etc/skel ] || cp -a $verbose /etc/skel/* /etc/skel/.[^.]* "\$HOME"/ ||:
mkdir -p $verbose -m700 -- "\$TMPDIR"
rpminit $verbose
cat >>/usr/src/.rpmmacros <<\EOF
%packager Automated package hasher <hasher@localhost>
%buildhost ${USER:-`id -nu`}.hasher.altlinux.org
%__BTE hasher
%__nprocs $nprocs
${contents_index_bin:+%_pkg_contents_index_bin /.host/contents_index_bin}
%_rpmbuild_clean 0
${repackage_source:+%_rpmbuild_packagesource 1}
EOF
__EOF__

	wlimit_time_elapsed=$wlimit_time_short wlimit_time_idle=$wlimit_time_short wlimit_bytes_written=$wlimit_bytes_out \
	    chrootuid2 &&
		Verbose "Created RPM build directory tree." ||
		Fatal 'Failed to create RPM build directory tree.'
fi # $build_list

purge_chroot_in
purge_chroot_out
