#!/bin/ksh -p
#

#set -x

# nbld-livecd - second phase bootstrap: miniroot => ISO
#
##############################################################################

#
# Copyright (C) 2005-2008 Nexenta Systems, Inc.
# All rights reserved.
#
##############################################################################

test ! -f /etc/nbld.cf && echo "Error: can't find /etc/nbld.cf" && exit 1
. /etc/nbld.cf

PATH=/usr/gnu/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb:/usr/ccs/bin 
export PATH
umask 0222

#SED="/usr/bin/sed"
SED="/usr/gnu/bin/sed"

MODE=livecd
#REPO=/usr/illumian
REPO=/usr/instarch

#
# CUSTOM_DIR specifies the location where customized LiveCD
# files are located at;
# By default CUSTOM_DIR is set to /usr/lib/nbld and can
# be overridden if necessary.
#
CUSTOM_DIR="$NBLD_LIBDIR"

#
# STAGING_DIR specifies the staging area used throughout the
# LiveCD creation process
#
STAGING_DIR="$NBLD_STAGING"

#
# LIVE64 specifies whether or not the miniroot and LiveCD
# contain 64-bit binaries.  By default only 32-bit binaries
# are copied over from miniroot staging area.  To enable this,
# set LIVE64 to 'y' in your shell environment prior to
# executing this script.
#
LIVE64=${LIVE64:-y}

#
# USE_ZFS specifies whether or not we use ZFS device pool
# to store /usr and other directories to be mounted from
# the CD-ROM.
#
USE_ZFS=${USE_ZFS:-n}

#
# USE_CLOFI specifies whether or not we use compressed file
# to store /usr and other directories to be mounted from
# the CD-ROM.
#
USE_CLOFI=${USE_CLOFI:-y}
CLOFI_ARCHIVE=usr.img

#
# VOLID specifies the CD-ROM volume ID of the LiveCD;
# by default it is set to "Elatte_LiveCD".
#
VOLID=${VOLID:=Elatte_LiveCD}

#
# ISO_IMAGE specifies the path and filename of the ISO
# generated by this script.  By default, it will be stored
# under the staging directory and named "elatte_live.iso".
#
ISO_IMAGE=${ISO_IMAGE:=${STAGING_DIR}/elatte_live.iso}

FAKEROOT="$NBLD_MINIROOT"

NODENAME=elatte_livecd

#
# The following variables are used internally and should
# not be set by the user under normal circumstances.
#
CWD=`pwd`

POOL_NAME=.pool_name
THIS_POOL=usrpool
POOL_MNT=.pool_mnt
POOL_MNTDIR=/var/tmp/${THIS_POOL}.mnt
MDISCO=${CUSTOM_DIR}/mdisco
SYSIDTOOL_XML=${CUSTOM_DIR}/nexenta-sysidtool.xml
SYSIDTOOL_NET=${CUSTOM_DIR}/nexenta-sysidtool-net
SYSIDTOOL_SYSTEM=${CUSTOM_DIR}/nexenta-sysidtool-system
SMF_PROFILE=${CUSTOM_DIR}/nexenta_livecd.xml
DIALOGRC=${CUSTOM_DIR}/nexenta-dot-dialogrc
FS_ROOT_CODE=${CUSTOM_DIR}/fs_root_code.sh
OO2_REG_CODE=${CUSTOM_DIR}/openoffice2_noreg.xml
OO2_SETUP_XCU=usr/openoffice.org2.0/share/registry/data/org/openoffice/Setup.xcu
USRMOUNT=/lib/svc/method/nexenta-usrmount
GRUB_MENU=${CUSTOM_DIR}/grub_menu.txt
HDD_GRUB_MENU=${CUSTOM_DIR}/hdd_grub_menu.txt
SERVER_GRUB_MENU=${CUSTOM_DIR}/${NBLD_DEFAULT_MODE}_grub-menu.txt
RELEASE_FILE=${CUSTOM_DIR}/release.txt
MINI_FILELIST=${CUSTOM_DIR}/filelist_miniroot.txt
CD_DIRLIST=.cd_dirlist
DHCP_EVENTHOOK=${CUSTOM_DIR}/eventhook
ISO_STAGING="$NBLD_STAGING/iso_staging.tmp"
BOOT_DIR=${ISO_STAGING}/boot
PLATFORM_DIR=${ISO_STAGING}/platform/i86pc
PLATFORM_PV_DIR=${ISO_STAGING}/platform/i86xpv
MINIROOT_STAGING="$NBLD_STAGING/miniroot_staging.tmp"
MINIROOT_STAGING_32b="$NBLD_STAGING/miniroot_staging_32b.tmp"
MINIROOT_STAGING_64b="$NBLD_STAGING/miniroot_staging_64b.tmp"
FILES="$NBLD_TMP/files.$$"
RAMDISK_FILE="$NBLD_TMP/miniroot.$$"
RAMDISK_MNT="$NBLD_TMP/miniroot_mount.$$"
REPO_FILE="$NBLD_TMP/repository.db.$$"
TMP_FILE="$NBLD_TMP/tmp_file.$$"

#CPIO=/usr/sun/bin/cpio
CPIO="/usr/bin/cpio"
test -f /usr/sun/bin/cpio && CPIO=/usr/sun/bin/cpio

ZFS_VDEV=/.livecd/${THIS_POOL}
MEMTEST=${CUSTOM_DIR}/memtest86+-2.11.bin

function aborted
{
	cleanup
	echo "Exiting."
	exit 0
}

trap 'aborted' INT HUP EXIT

function fatal_error
{
	cleanup
	echo
	echo "Fatal error."
	exit 1
}

function cleanup
{
	rm -f ${REPO_FILE} 2> /dev/null
	umount -f ${RAMDISK_MNT} 2>/dev/null
	lofiadm -d ${RAMDISK_FILE} 2>/dev/null
	rm -rf ${RAMDISK_FILE} ${RAMDISK_FILE}.gz ${RAMDISK_MNT} 2> /dev/null
	rm -rf ${MINIROOT_STAGING} 2> /dev/null
	rm -rf ${ISO_STAGING} 2> /dev/null
	rm -f ${TMP_FILE} 2> /dev/null
	rm -f ${FILES} 2> /dev/null
	unshare -F nfs ${FAKEROOT} >/dev/null 2>&1
}

function create_dir
{
	dir=$1
	mode=$2
	owner=$3

	mkdir -p ${dir} || fatal_error
	chmod ${mode} ${dir} || fatal_error
	chown ${owner} ${dir} || fatal_error
}

function copy_file
{
	src=$1
	dst=$2
	mode=$3
	owner=$4

	cp ${src} ${dst} || fatal_error
	chmod ${mode} ${dst} || fatal_error
	chown ${owner} ${dst} || fatal_error
}

installcd_excl='
system/cron
system/fmd
system/picl
system/device/devices-fc-fabric
system/filesystem/autofs
system/intrd
system/dumpadm
network/pfil
network/rpc/mdcomm
network/rpc/meta
network/rpc/metamed
network/rpc/metamh
network/rpc/gss
network/rpc/rquota
network/nfs/status
network/nfs/nlockmgr
network/nfs/client
network/nfs/server
network/nfs/rquota
network/security/ktkt_warn
application/gdm
'

function bootstrap_repository
{
	# Grab the list of all manifests under var/svc/manifest
	alt_root=$1

	mkdir -p ${alt_root}/etc/ssh
	/usr/bin/ssh-keygen -q -f ${alt_root}/etc/ssh/ssh_host_rsa_key -t rsa -N ''
	/usr/bin/ssh-keygen -q -f ${alt_root}/etc/ssh/ssh_host_dsa_key -t dsa -N ''

	if [ "${MODE}" != "livecd" ]; then
		eval echo "\"\$installcd_excl\""  | \
		while read mft; do
			test "x${mft}" = "x" && continue
			rm -f ${alt_root}/lib/svc/manifest/${mft}.xml
		done
	fi

	manifest_list=`find ${alt_root}/lib/svc/manifest/* \
	    -type f -name "*.xml" -print`

	set -- ${manifest_list}
        backup=`echo "[$#/$#] ... " | $SED 's/.//g'`
        fwidth=`echo "$#\c" | wc -c`

#	CONFIGD=/lib/svc/bin/svc.configd
#	SVCCFG=/usr/sbin/svccfg
	CONFIGD=${FAKEROOT}/lib/svc/bin/svc.configd
	SVCCFG=${FAKEROOT}/usr/sbin/svccfg
	DTD=${FAKEROOT}/usr/share/lib/xml/dtd/service_bundle.dtd.1
#	SVCENV="NLU_ENABLED=1 LD_NOAUXFLTR=1 LD_LIBRARY_PATH=/tmp/nlulib:$LD_LIBRARY_PATH \
#		LD_LIBRARY_PATH_64=/tmp/nlulib/64:$LD_LIBRARY_PATH_64 SVCCFG_CHECKHASH=1 \
#		PKG_INSTALL_ROOT=${alt_root} SVCCFG_DTD=${DTD} \
#		SVCCFG_REPOSITORY=${REPO_FILE} SVCCFG_CONFIGD_PATH=${CONFIGD}"
	SVCENV="SVCCFG_CHECKHASH=1 \
		PKG_INSTALL_ROOT=${alt_root} SVCCFG_DTD=${DTD} \
		SVCCFG_REPOSITORY=${REPO_FILE} SVCCFG_CONFIGD_PATH=${CONFIGD}"

	echo "  bootstrapping smf repository \c"

	# Create the repository with smf/manifest property
	eval "${SVCENV} ${SVCCFG} add smf/manifest"

	i=1; n=$#
	while [ $# -gt 0 ]; do
		printf "[%${fwidth}s/%${fwidth}s] ... " $i $n

		# Import manifests into the repository
		eval "${SVCENV} ${SVCCFG} import $1"

		i=`expr $i + 1`
		shift
		if [ $# -ne 0 ]; then
			echo "${backup}\c"
		fi
	done


	cd ${alt_root}/etc/svc/profile
	rm -f inetd_services.xml
	ln -f -s inetd_generic.xml inetd_services.xml

	rm -f name_service.xml
	ln -f -s ns_dns.xml name_service.xml

	rm -f platform.xml
	ln -f -s platform_none.xml platform.xml

#	ln -f -s generic_limited_net.xml generic.xml
#	mv generic_limited_net.xml generic_limited_net.xml.temp
#	cat generic_limited_net.xml.temp | $SED -e "s#file:/etc/svc/profile/name_service.xml#name_service.xml#" > generic_limited_net.xml

#	mv generic_limited_net.xml generic_limited_net.xml.temp
#	cat generic_limited_net.xml | $SED -e "s/\(vt[0-9].*enabled=.\)true/false/" > generic_limited_net.xml

#	mv generic_limited_net.xml generic_limited_net.xml.temp
#	cat generic_limited_net.xml | $SED -e "/system\/coreadm/{n; s/true/false/}" > generic_limited_net.xml

	rm -f generic.xml
	ln -f -s generic_limited_net.xml generic.xml
	$SED -i -e "s#file:/etc/svc/profile/name_service.xml#name_service.xml#" generic.xml
	$SED -i -e "s/\(vt[0-9].*enabled=.\)true/false/" generic.xml
	$SED -i -e "/system\/coreadm/{n; s/true/false/}" generic.xml
	cd ${OLDPWD}

	eval "${SVCENV} ${SVCCFG} apply ${alt_root}/etc/svc/profile/generic.xml"

	eval "${SVCENV} ${SVCCFG} apply ${alt_root}/etc/svc/profile/platform.xml"

	# Apply LiveCD profile
	eval "${SVCENV} ${SVCCFG} apply ${SMF_PROFILE}"

	# turnoff boot-archive, manifest-import
#	eval "${SVCENV} ${SVCCFG} -s system/boot-archive setprop config/auto-reboot-safe = false"
	eval "${SVCENV} ${SVCCFG} -s system/boot-archive setprop general/enabled=false"
	eval "${SVCENV} ${SVCCFG} -s system/boot-archive setprop start/exec=:true"

	# Store the repository under etc/svc/repository.db
	chown root:sys ${REPO_FILE}
	mv ${REPO_FILE} ${alt_root}/etc/svc/repository.db

	echo "done"
}

function customize_mini
{
	oldpwd=${PWD}

	# This is where the LiveCD gets mounted at
	mkdir $1/.livecd
	chown root:sys $1/.livecd

	echo "${VOLID}" > $1/.volid
	chown root:sys $1/.volid

	# We need device reconfiguration
	touch $1/reconfigure

	# We need auto network reconfiguration on boot for LiveCD only
	if [ "${MODE}" = "livecd" ]; then
		touch $1/etc/.UNCONFIGURED
	fi

	# Tell NFS4 to not prompt us for default domain
	touch $1/etc/.NFS4inst_state.domain

	# Prepare system to use DNS
	if [ -f $1/etc/resolv.conf ]; then
		rm $1/etc/resolv.conf
	fi
	touch $1/etc/resolv.conf
	cp $1/etc/nsswitch.dns $1/etc/nsswitch.conf
	copy_file ${DHCP_EVENTHOOK} \
	    $1/etc/dhcp/`basename ${DHCP_EVENTHOOK}` 0755 root:sys

	# Bootstrap /etc/hosts entry
	node_fqdn="${NODENAME}.localdomain"
	hosts_entry="127.0.0.1\t${NODENAME}\t${node_fqdn}\tloghost"
	echo "${hosts_entry}" >> $1/etc/hosts

	echo "${NODENAME}" > $1/etc/nodename
	chmod 0644 $1/etc/nodename
	chown root:root $1/etc/nodename

	echo "setprop prealloc-chunk-size 0x2000" >> $1/boot/solaris/bootenv.rc

	# Make sure root special device is known at boot time
	CHK=`cat $1/etc/vfstab | grep "devices/ramdisk:a" | wc -l`
	if (( $CHK < 1 )); then
	    echo "/devices/ramdisk:a\t-\t/\t\tufs\t1\tno\trw" >> $1/etc/vfstab
	fi

	# Get us as much swap space as possible
	echo "set tmpfs:tmpfs_minfree=1" >> $1/etc/system
	echo "set swapfs_minfree=0x40" >> $1/etc/system

	# to avoid timeouts with some ATA controllers...
	echo "set use_mp=0" >> $1/etc/system

	#
	# We don't want to keep accessing the disk(s) every
	# so often for fsflush, etc. so we do some tuning.
	#
	#echo "set tune_t_fsflushr=900" >> $1/etc/system
	#echo "set autoup=900" >> $1/etc/system

	# Tell ZFS to go into read-only mode

	# Adjust ATA driver standby timeout
	#echo "standby=300;" >> $1/platform/i86pc/kernel/drv/ata.conf

	# Copy over customized SMF manifests and methods
	copy_file ${SYSIDTOOL_XML} \
	    $1/lib/svc/manifest/system/`basename ${SYSIDTOOL_XML}` 0444 root:sys

	copy_file ${SYSIDTOOL_NET} \
	    $1/lib/svc/method/`basename ${SYSIDTOOL_NET}` 0555 root:bin

	copy_file ${SYSIDTOOL_SYSTEM} \
	    $1/lib/svc/method/`basename ${SYSIDTOOL_SYSTEM}` 0555 root:bin

	# Copy over our media discovery utility
	if [ -f ${MDISCO} ]; then
		copy_file ${MDISCO} $1/sbin/`basename ${MDISCO}` 0755 root:bin
	else
		echo "\nError: ${MDISCO} not found"
		fatal_error
	fi

	if [ "${MODE}" = "livecd" ]; then
		# Set LiveCD root password to "livecd"
		$SED 's/^root:/root:pv80DlPSjDfZI/g' $1/etc/shadow > ${TMP_FILE}
		copy_file ${TMP_FILE} $1/etc/shadow 0400 root:sys
		rm ${TMP_FILE}
	else
		# Set InstallCD root password to "empty"
		$SED 's/^root:/root:moAdagpFPw1iE/g' $1/etc/shadow > ${TMP_FILE}
		copy_file ${TMP_FILE} $1/etc/shadow 0400 root:sys
		rm ${TMP_FILE}
	fi

	# Set root shell to /bin/bash
	$SED 's/sbin\/sh/bin\/bash/g' $1/etc/passwd > ${TMP_FILE}
#	sed 's/sbin\/sh/bin\/sh/g' $1/etc/passwd > ${TMP_FILE}
#	sed 's/usr\/bin\/bash/bin\/sh/g' $1/etc/passwd > ${TMP_FILE}
	copy_file ${TMP_FILE} $1/etc/passwd 0644 root:sys
	rm ${TMP_FILE}

	# Allow root login via SSH
	if [ -f $1/etc/ssh/sshd_config ]; then
		$SED '/^PermitRootLogin/ s/no/yes/g' \
		    $1/etc/ssh/sshd_config > ${TMP_FILE}
		copy_file ${TMP_FILE} $1/etc/ssh/sshd_config 0644 root:sys
		rm ${TMP_FILE}
	fi

	# Allow root login via telnet
	$SED -e 's/^CONSOLE/#CONSOLE/' $1/etc/default/login > ${TMP_FILE}
	copy_file ${TMP_FILE} $1/etc/default/login 0644 root:sys
	rm ${TMP_FILE}

	#
	# The fs-root script in lib/svc/method does all the /usr
	# mounting at boot time; we insert our customized code in
	# this file in order for us to discover and mount LiveCD
	# on /.livecd, as well as mount /usr on top of that.
	#
	copy_file ${FS_ROOT_CODE} $1/${USRMOUNT} 0555 root:bin
	sed -e "/^\. \/lib\/svc\/share\/fs_include\.sh/ a . ${USRMOUNT}" \
	    $1/lib/svc/method/fs-root > ${TMP_FILE}

	cp ${TMP_FILE} $1/lib/svc/method/fs-root
	rm ${TMP_FILE}

	# Hard-code timezone to US/Pacific
	echo "zone_info=US/Pacific" > $1/etc/rtc_config
	echo "zone_lag=28800" >> $1/etc/rtc_config
	sed -e 's/PST8PDT/US\/Pacific/' < $1/etc/default/init > ${TMP_FILE}
	cp ${TMP_FILE} $1/etc/default/init
	rm ${TMP_FILE}

	#
	# Work around GNU's "uname -S" problem; we use /bin/hostname
	# to set machine's hostname instead.  We should probably fix
	# GNU's uname at some point.
	#
	sed -e 's/sbin\/uname\ -S/bin\/hostname/' < \
	    $1/lib/svc/method/identity-node > ${TMP_FILE}
	cp ${TMP_FILE} $1/lib/svc/method/identity-node
	rm ${TMP_FILE}

	# Set up dialog RC file for InstallCD
	if [ "${MODE}" != "livecd" ]; then
		cp -f ${DIALOGRC} $1/root/.dialogrc
		if cat ${FAKEROOT}/${REPO}/defaults | grep "nlm-eval:" >/dev/null; then
			sed -i -e "s/NexentaStor/Community Edition/" $1/root/.screenrc
		elif cat ${FAKEROOT}/${REPO}/defaults | grep "nlm-com:" >/dev/null; then
			sed -i -e "s/NexentaStor/Enterprise Edition/" $1/root/.screenrc
		fi
	fi

	cp ${CUSTOM_DIR}/DRIVER-INSTALL.txt $1/

	#
	# Import all manifests at this time so that SMF doesn't
	# re-import them during boot (this saves us some time).
	#
	bootstrap_repository $1

	cd ${oldpwd}
}

function create_mini
{
	echo "Creating miniroots...."
	# Find out the size of miniroot staging area
	sync; sync; sync
	sleep 5 #this should give du time to see the correct file size
	total_size_32b=`du -sk ${MINIROOT_STAGING_32b} | nawk '{print $1}'`
	total_size_64b=`du -sk ${MINIROOT_STAGING_64b} | nawk '{print $1}'`
	
	# Add some extra space for our root filesystem
	if [ "${MODE}" = "livecd" ]; then
#		(( total_size_32b += total_size_32b * 50 / 100 ))
		(( total_size_64b += total_size_64b * 50 / 100 ))
	else
#		(( total_size_32b += total_size_32b * 15 / 100 ))
		(( total_size_64b += total_size_64b * 15 / 100 ))
	fi

#	echo "  Create 32 bit miniroot..."
	create_mini_stage2 ${MINIROOT_STAGING_32b} ${PLATFORM_DIR} $total_size_32b
#	test -d ${MINIROOT_STAGING_32b} && rm -rf ${MINIROOT_STAGING_32b}
	echo "  Create 64 bit miniroot..."
	create_mini_stage2 ${MINIROOT_STAGING_64b} "${PLATFORM_DIR}/amd64" $total_size_64b
#	test -d ${MINIROOT_STAGING_64b} && rm -rf ${MINIROOT_STAGING_64b}

}

function create_mini_stage2
{
	DEST=$2
	total_size=$3

	echo "    preparing ramdisk image ... \c"

	# Compress miniroot image
	test -d ${DEST} || mkdir -p ${DEST}
	BITS=`basename $DEST`
	if [ "$BITS" = "amd64" ]; then
	cp $NBLD_TMP/miniroot.64 ${DEST}/miniroot
	else
	cp $NBLD_TMP/miniroot.32 ${DEST}/miniroot
	fi
	sync; sync
	sleep 1
	du -sh ${DEST}/miniroot | read size name

	echo "done (${size}, compressed)"
}

function create_grub
{
	echo "  preparing GRUB ... \c"

	cd ${FAKEROOT}/boot
	tar cf - grub | (cd ${BOOT_DIR}; umask 0; tar xpf -)
	cd ${OLDPWD}

	cd ${FAKEROOT}/platform/i86pc 
	tar cf - kernel | (cd ${PLATFORM_DIR}; umask 0; tar xpf -)
	cd ${OLDPWD}

	cd ${FAKEROOT}/platform/i86xpv
	tar cf - kernel | (cd ${PLATFORM_PV_DIR}; umask 0; tar xpf -)
	cd ${OLDPWD}

	# Copy over customized GRUB menu
	if [ "${MODE}" = "livecd" ]; then
		MENU=${GRUB_MENU}
	else
		if [ "${INSTALL_MODE}" = "core" ]; then
			MENU=${SERVER_GRUB_MENU}
		else
			MENU=${HDD_GRUB_MENU}
		fi
	fi

	if [ -f ${MENU} ]; then
		copy_file ${MENU} ${BOOT_DIR}/grub/menu.lst 0644 root:root
		sed -e "s/__autoversion__/$os_version, software $sw_version/" -i ${BOOT_DIR}/grub/menu.lst
#		cp ${BOOT_DIR}/grub/menu.lst ${FAKEROOT}/boot/grub/menu.lst.inst
#		cp ${BOOT_DIR}/grub/menu.lst ${BOOT_DIR}/grub/menu.lst.inst
	fi

	if [ -f ${MEMTEST} ]; then
		copy_file ${MEMTEST} ${BOOT_DIR}/memtest86+.bin 0644 root:root
	fi

#	cp ${BOOT_DIR}/grub/menu.lst ${BOOT_DIR}/grub/menu.lst.inst

	if [ -f ${MENU} ]; then
	    echo "title Boot from Local HDD" >> ${BOOT_DIR}/grub/menu.lst
	    echo "	root (hd0,0)" >> ${BOOT_DIR}/grub/menu.lst
	    echo "	chainloader +1" >> ${BOOT_DIR}/grub/menu.lst
	fi

	echo "done"
}

function customize_usr
{
	if [ -f ${FAKEROOT}/${OO2_SETUP_XCU} ]; then
		grep "LicenseAcceptDate" ${FAKEROOT}/${OO2_SETUP_XCU} \
		    > /dev/null
		if [ $? -ne 0 ]; then
			rm -f ${TMP_FILE} 2> /dev/null
			sed -e "/<node oor:name=\"Office\">/ r ${OO2_REG_CODE}"\
			    ${FAKEROOT}/${OO2_SETUP_XCU} > ${TMP_FILE}
			cp ${TMP_FILE} ${FAKEROOT}/${OO2_SETUP_XCU}
		fi
	fi

	ln -sf ../../usr/instarch/hwdisco ${FAKEROOT}/usr/bin/hwdisco
}

iso_excl='
usr/share/locale/aa
usr/share/locale/bg
usr/share/locale/de
usr/share/locale/ga
usr/share/locale/hy
usr/share/locale/km
usr/share/locale/lo
usr/share/locale/ms
usr/share/locale/oc
usr/share/locale/ro
usr/share/locale/sp
usr/share/locale/tg
usr/share/locale/ur
usr/share/locale/yi
usr/share/locale/af
usr/share/locale/bn
usr/share/locale/dv
usr/share/locale/eo
usr/share/locale/gez
usr/share/locale/ia
usr/share/locale/kn
usr/share/locale/mt
usr/share/locale/om
usr/share/locale/ru
usr/share/locale/sq
usr/share/locale/th
usr/share/locale/urd
usr/share/locale/yo
usr/share/locale/am
usr/share/locale/br
usr/share/locale/dz
usr/share/locale/es
usr/share/locale/gl
usr/share/locale/id
usr/share/locale/ko
usr/share/locale/lt
usr/share/locale/my
usr/share/locale/or
usr/share/locale/rw
usr/share/locale/sr
usr/share/locale/ti
usr/share/locale/uz
usr/share/locale/zh
usr/share/locale/an
usr/share/locale/bs
usr/share/locale/el
usr/share/locale/et
usr/share/locale/gu
usr/share/locale/is
usr/share/locale/kok
usr/share/locale/lv
usr/share/locale/my_MM
usr/share/locale/pa
usr/share/locale/sa
usr/share/locale/sr@Latn
usr/share/locale/tig
usr/share/locale/uz@Latn
usr/share/locale/zh_CN
usr/share/locale/ang
usr/share/locale/byn
usr/share/locale/eu
usr/share/locale/gv
usr/share/locale/it
usr/share/locale/ku
usr/share/locale/mg
usr/share/locale/nb
usr/share/locale/pa_IN
usr/share/locale/se
usr/share/locale/sr@ije
usr/share/locale/tk
usr/share/locale/ve
usr/share/locale/zh_CN.GB2312
usr/share/locale/ar
usr/share/locale/ca
usr/share/locale/en@boldquot
usr/share/locale/eu_ES
usr/share/locale/haw
usr/share/locale/iu
usr/share/locale/kw
usr/share/locale/mi
usr/share/locale/ne
usr/share/locale/pl
usr/share/locale/si
usr/share/locale/sv
usr/share/locale/tl
usr/share/locale/vi
usr/share/locale/zh_HK
usr/share/locale/as
usr/share/locale/co
usr/share/locale/en@quot
usr/share/locale/fa
usr/share/locale/he
usr/share/locale/ja
usr/share/locale/ky
usr/share/locale/mk
usr/share/locale/nl
usr/share/locale/ps
usr/share/locale/sid
usr/share/locale/sw
usr/share/locale/tr
usr/share/locale/wa
usr/share/locale/zh_TW
usr/share/locale/az
usr/share/locale/cs
usr/share/locale/en_AU
usr/share/locale/fi
usr/share/locale/hi
usr/share/locale/ka
usr/share/locale/lb
usr/share/locale/ml
usr/share/locale/nn
usr/share/locale/pt
usr/share/locale/sk
usr/share/locale/syr
usr/share/locale/tt
usr/share/locale/wal
usr/share/locale/zu
usr/share/locale/az_IR
usr/share/locale/cy
usr/share/locale/en_CA
usr/share/locale/fo
usr/share/locale/hr
usr/share/locale/kk
usr/share/locale/lg
usr/share/locale/mn
usr/share/locale/no
usr/share/locale/pt_BR
usr/share/locale/sl
usr/share/locale/ta
usr/share/locale/ug
usr/share/locale/wo
usr/share/locale/be
usr/share/locale/da
usr/share/locale/en_GB
usr/share/locale/fr
usr/share/locale/hu
usr/share/locale/kl
usr/share/locale/li
usr/share/locale/mr
usr/share/locale/nso
usr/share/locale/rm
usr/share/locale/so
usr/share/locale/te
usr/share/locale/uk
usr/share/locale/xh
usr/share/doc
'
#var/lib/dpkg/alien

function create_usr
{
	if [ "${LIVE64}" != "y" ]; then
		exclude64="-type d -name amd64 -prune -o"
#		exclude64="-name *"
		exclude64_msg=" (excluding 64-bit)"
	fi

	echo "  creating CD-ROM based directories${exclude64_msg}:"

	mkdir -p ${ISO_STAGING}/root
	chown root:root ${ISO_STAGING}/root

	cd ${FAKEROOT}

	echo "    copying /usr ... \c"
 	find usr ${exclude64} -print | \
	    ${CPIO} -pdum ${ISO_STAGING}/root 2> /dev/null
	echo "done"

	# now take care of any excluded entries
	egrep -e '^[ \t]*!' ${MINI_FILELIST} | sed -e "s/\!//g" | \
	nawk '{ print $1 }' | while read dirname; do
		if [ -e ${dirname} ]; then
			echo "    copying /${dirname} ... \c"
			find ${dirname} ${exclude64} -print | \
			    ${CPIO} -pdum ${ISO_STAGING}/root 2> /dev/null
			echo "done"
		fi
	done

	echo "    cleaning ${ISO_STAGING}/root ... \c"
	eval echo "\"\$iso_excl\""  | \
	while read dir; do
		test "x${dir}" = "x" && continue
		rm -rf ${ISO_STAGING}/root/${dir}
	done
	echo "done"
}

function create_usr_clofi
{
	create_usr

	echo "    archiving ${ISO_STAGING}/root/usr ... \c"
	/usr/bin/mkisofs -o ${ISO_STAGING}/${CLOFI_ARCHIVE} -N -l -R -U -allow-multidot -no-iso-translate -cache-inodes -d -D -V "compress" ${ISO_STAGING}/root/usr >/dev/null 2>&1
	if [ $? -ne 0 ]; then
		echo "Error archiving - not enough space at ${CLOFI_ARCHIVE}/.. ?"
		exit 1
	fi
	echo "done"

	echo "    compressing ${CLOFI_ARCHIVE} ... \c"
	lofiadm -C gzip ${ISO_STAGING}/${CLOFI_ARCHIVE}
	mv ${ISO_STAGING}/${CLOFI_ARCHIVE} ${ISO_STAGING}/${CLOFI_ARCHIVE}.zlib
	if [ $? -ne 0 ]; then
		echo "Error archiving - not enough space at ${ISO_STAGING}/.. ?"
		exit 1
	fi

	rm -rf ${ISO_STAGING}/root ${ISO_STAGING}/${CLOFI_ARCHIVE}
	echo "done"
}

function pool_cleanup
{
	quit=$1
	/usr/sbin/zpool list -H | nawk '{ print $1 }' | grep ${THIS_POOL}
	if [ $? -eq 0 ]; then
		/usr/sbin/zpool export -f ${THIS_POOL}
	fi
	rm -rf ${POOL_MNTDIR} >/dev/null 2>&1
	rm -rf /.livecd
	test "x$quit" = x1 && exit 1
}

function create_usr_zfs
{
	if [ "${LIVE64}" != "y" ]; then
		exclude64="amd64"
#		exclude64=""
		exclude64_msg="64-bit directories"
	fi

	if [ -f ${ZFS_VDEV} ]; then
		rm -f ${ZFS_VDEV}
	fi

	mkdir /.livecd

	dirlist=`cat ${FAKEROOT}/${MINIROOT_STAGING}/${CD_DIRLIST} | \
	    sed -e 's/\/$//g'`

	DIRLIST="${dirlist}"
	ISO_EXCL="${iso_excl}"

	if [ "${THIS_POOL}" = "" ]; then
		echo "Error: pool name must be set."
		exit 1
	fi

	echo "  creating ZFS device pool ${ZFS_VDEV}"

	POOL_SIZE_MB=`/usr/gnu/bin/du ${FAKEROOT}/usr -B MB -c --summarize | grep total | sed -e 's/MB//g' | nawk '{ print $1 }'`

	echo "    creating ZFS pool (${POOL_SIZE_MB} MB) ... \c"
	/usr/sbin/mkfile ${POOL_SIZE_MB}M ${ZFS_VDEV}
	if [ $? -ne 0 ]; then
		echo "Error creating ${ZFS_VDEV} of ${POOL_SIZE_MB} MB."
		pool_cleanup 1
	fi
	/usr/sbin/zpool create -m ${POOL_MNTDIR} ${THIS_POOL} ${ZFS_VDEV}
	if [ $? -ne 0 ]; then
		echo "Error creating ZFS pool: ${THIS_POOL} using vdev ${ZFS_VDEV}"
		pool_cleanup 1
	fi
	echo "done"

	/usr/sbin/zfs set compression=on ${THIS_POOL}
	/usr/sbin/zfs set atime=off ${THIS_POOL}

	exclude=""
	echo "${ISO_EXCL}" | \
	while read dirnocopy; do
		if [ "${dirnocopy}" != "" -a -e ${dirnocopy} ]; then
			echo "${dirnocopy}" | /bin/grep / >/dev/null 2>&1
			if [ $? -eq 0 ]; then
				matcharg="-type d -wholename"
			else
				matcharg="-type d -name"
			fi

			if [ "${exclude}" = "" ]; then
				exclude="${matcharg} ${dirnocopy}"
			else
				exclude="${exclude} -o ${matcharg} ${dirnocopy}"
			fi
		fi
	done

	if [ "${exclude64}" != "" ]; then
		echo "    skipping ${exclude64_msg} ... \c"
		if [ "${exclude}" = "" ]; then
			exclude="-type d -name ${exclude64}"
		else
			exclude="${exclude} -o -type d -name ${exclude64}"
		fi
		echo "done"
	fi

	if [ "${exclude}" != "" ]; then
		exclude="( ${exclude} ) -prune -o"
	fi

	echo "${DIRLIST}"  | \
	while read dirname; do
		if [ -e ${dirname} ]; then
			echo "    copying /${dirname} ... \c"
			find ${dirname} ${exclude} -print | \
			    ${CPIO} -pdum ${POOL_MNTDIR} 2> /dev/null
			if [ $? -ne 0 ]; then
				echo "Error copying - ZFS pool is too small?"
				pool_cleanup 1
			fi
			echo "done"
		fi
	done

	/usr/sbin/zfs set readonly=on ${THIS_POOL}

	echo "    exporting ${THIS_POOL} ... \c"
	/usr/sbin/zpool export -f ${THIS_POOL}
	if [ $? -ne 0 ]; then
		echo "ZFS export failed for ${THIS_POOL}"
		pool_cleanup 1
	fi
	echo "done"

	if [ ! -f ${ZFS_VDEV} ]; then
		echo "Error creating ${THIS_POOL}"
		pool_cleanup 1
	fi

	echo "    moving pool to ${ISO_STAGING} ... \c"
	mv ${ZFS_VDEV} ${ISO_STAGING}
	chmod 400 ${ISO_STAGING}/${THIS_POOL}
	echo "done"

	pool_cleanup
}

function create_iso
{
	echo "Creating CD image:"

	create_grub
	customize_usr
	if [ "${USE_ZFS}" = "y" ]; then
		create_usr_zfs
	elif [ "${USE_CLOFI}" = "y" ]; then
		create_usr_clofi
	else
		create_usr
	fi

	echo "  creating ISO using ${ISO_STAGING} ... \c"
	cd ${ISO_STAGING}
	/usr/bin/mkisofs -l -allow-leading-dots -input-charset iso8859-1 \
		-R -N -d -D -V ${VOLID} \
		-c .catalog -b boot/grub/stage2_eltorito \
		-no-emul-boot -boot-load-size 4 -boot-info-table \
		-relaxed-filenames -quiet \
		-o ${ISO_IMAGE} ${ISO_STAGING} > /dev/null 2>&1

	if [ $? != 0 ]; then
		echo "FAILED"
		return 1
	fi

	sleep 1; sync
	size=$(du -sh ${ISO_IMAGE} | awk '{print $1}')

	echo "done (${size})"
	echo "CD image ${ISO_IMAGE} is ready"

	return 0
}

#
# Certain operations such as lofiadm, svccfg, etc. require root
# privileges.  Therefore bail out if this script is executed by
# non-root user.
#
# NOTE: It may be possible to get around this by setting up
# privileges for non-root users to do those operations, but
# until then we need to be root.  This is risky!
#
UID=`id -u`
if [ "$UID" != "0" ]; then
	echo "Insufficient privileges to run $0"
	exit 1
fi

# Make sure that essential directories are present
if [ ! -d ${CUSTOM_DIR} ]; then
	echo "Error: ${CUSTOM_DIR} does not exist"
	exit 1
elif [ ! -d ${FAKEROOT} ]; then
	echo "Error: ${FAKEROOT} does not exist"
	exit 1
fi

if test -f ${CUSTOM_DIR}/${NBLD_DEFAULT_MODE}.profile; then
	. ${CUSTOM_DIR}/${NBLD_DEFAULT_MODE}.profile
elif test -f ${NBLD_DEFAULT_MODE}.profile; then
	. ${NBLD_DEFAULT_MODE}.profile
else
	echo "Error: ${NBLD_DEFAULT_MODE}.profile not found."
	exit 1

fi

if [ -d ${FAKEROOT}/${REPO} ]; then
	LIVE64=y
	NODENAME=${NBLD_DEFAULT_MODE}_installcd
	VOLID=Nexenta_InstallCD
	MODE=install
	DATE_TIME="-$(date +%y-%m-%d_%H-%M)"
	ISO_IMAGE=${STAGING_DIR}/${NBLD_DEFAULT_MODE}_install${DATE_TIME}.iso
#	if cat ${FAKEROOT}/${REPO}/defaults | egrep "NexentaCore|NexentaStor" >/dev/null; then
		INSTALL_MODE=core
#	else
#		INSTALL_MODE=generic
#	fi
fi

if [ ${USE_ZFS} = "y" ]; then
	FS_ROOT_CODE=${CUSTOM_DIR}/fs_root_code_zfs.sh
fi

if [ ${USE_CLOFI} = "y" ]; then
	FS_ROOT_CODE=${CUSTOM_DIR}/fs_root_code_clofi.sh
fi

cat << EOF
==============================================================================
Mode:      ${MODE} ${INSTALL_MODE}
Staging:   ${STAGING_DIR}
Custom:    ${CUSTOM_DIR}
Fakeroot:  ${FAKEROOT}
==============================================================================
EOF

# Step 1: Cleanup
#echo "Cleaning up staging directory ... \c"
# Create staging directory if not already present
#if [ ! -d ${STAGING_DIR} ]; then
#	mkdir -p ${STAGING_DIR} || fatal_error
#fi

# Blow away existing ISO staging area
test -d ${ISO_STAGING} && rm -rf ${ISO_STAGING}
#test -d ${MINIROOT_STAGING} && rm -rf ${MINIROOT_STAGING}

mkdir -p ${PLATFORM_DIR} || fatal_error
mkdir -p ${PLATFORM_PV_DIR} || fatal_error
mkdir -p ${BOOT_DIR} || fatal_error
echo "done"

# Step 2: Create miniroot
create_mini

# Step 3: Create ISO
create_iso || fatal_error

# Step 4: Cleanup and we're done
cleanup
exit 0
