#! /bin/sh
set -e

. /usr/share/debconf/confmodule

question () {
	owner="$1"
	question="$2"
	qtype="$3"

	if db_get "$2"; then
		echo "$owner	$question	$qtype $RET" >>"$OUT"
	fi
}

made_preseed=
make_preseed_file () {
	# Generate a preseed file from this installation suitable for publication by
	# the cluster controller. The list of questions we copy is largely drawn
	# from the installation guide.

	if [ "$made_preseed" ]; then
		return
	fi
	made_preseed=1

	OUT=/target/etc/eucalyptus/preseed/preseed.conf
	mkdir -p "${OUT%/*}"
	>"$OUT"
	chroot /target chown eucalyptus:eucalyptus "${OUT#/target}" || true
	chmod 600 "$OUT"

	cat >>"$OUT" <<EOF
# These normally need to be passed as boot parameters instead, but are
# included here for completeness.
EOF
	question d-i debian-installer/locale string
	question d-i console-setup/ask_detect boolean
	question d-i console-setup/layoutcode string
	question d-i console-setup/variantcode string
	question d-i netcfg/get_nameservers string
	question d-i netcfg/get_ipaddress string
	question d-i netcfg/get_netmask string
	question d-i netcfg/get_gateway string
	question d-i netcfg/confirm_static boolean

	echo >>"$OUT"

	question d-i mirror/protocol string
	question d-i mirror/country string
	question d-i mirror/http/hostname string
	question d-i mirror/http/directory string
	question d-i mirror/http/proxy string
	question d-i mirror/http/mirror select
	question d-i mirror/suite string
	question d-i mirror/udeb/suite string
	question d-i mirror/udeb/components multiselect

	question d-i clock-setup/utc boolean
	question d-i time/zone string
	question d-i clock-setup/ntp boolean
	question d-i clock-setup/ntp-server string

	# TODO partitioning?

	question d-i base-installer/kernel/image string
	question d-i passwd/root-login boolean
	question d-i passwd/make-user boolean
	ROOTPW="$(grep '^root:' /target/etc/shadow 2>/dev/null | head -n1 | cut -d: -f2)"
	if [ -n "$ROOTPW" ] && [ "x$ROOTPW" != 'x*' ] && [ "x$ROOTPW" != 'x!' ]; then
		echo "d-i	passwd/root-password-crypted	password $ROOTPW" >>"$OUT"
	fi
	ROOTPW=
	if db_get passwd/make-user && [ "$RET" = true ]; then
		question d-i passwd/user-fullname string
		question d-i passwd/username string
		if db_get passwd/username && [ -n "$RET" ]; then
			USERPW="$(grep "^$RET:" /target/etc/shadow 2>/dev/null | head -n1 | cut -d: -f2)"
			if [ -n "$USERPW" ] && [ "x$USERPW" != 'x*' ] && [ "x$USERPW" != 'x!' ]; then
				echo "d-i	passwd/user-password-crypted	password $USERPW" >>"$OUT"
			fi
			USERPW=
		fi
		question d-i passwd/user-uid string
		question d-i user-setup/allow-password-weak boolean
		question d-i user-setup/encrypt-home boolean
		question d-i passwd/user-default-groups string
	fi

	question d-i apt-setup/restricted boolean
	question d-i apt-setup/universe boolean
	question d-i apt-setup/backports boolean
	question d-i apt-setup/use_mirror boolean
	question d-i 'apt-setup/services-select' multiselect
	question d-i apt-setup/security_host string
	question d-i apt-setup/security_path string
	# TODO apt-setup/local*/{repository,comment,source,key}
	question d-i debian-installer/allow_unauthenticated string

	# Tasks will be set differently during node installation.
	question d-i pkgsel/upgrade select
	question d-i pkgsel/language-packs multiselect
	question d-i pkgsel/update-policy select
	question popularity-contest popularity-contest/participate boolean
	question d-i pkgsel/updatedb boolean

	question d-i grub-installer/skip boolean
	question d-i lilo-installer/skip boolean
	question d-i grub-installer/only_debian boolean
	question d-i grub-installer/with_other_os boolean
	question d-i grub-installer/bootdev string
	# TODO grub password?

	question d-i finish-install/keep-consoles boolean
	question d-i finish-install/reboot_in_progress note
	question d-i cdrom-detect/eject boolean
	question d-i debian-installer/exit/halt boolean
	question d-i debian-installer/exit/poweroff boolean

	# This owner is a bit of a cheat, but it does at least mean that the
	# question will be purged if all eucalyptus packages are purged.
	case " $components " in
	    *' cluster '*)
		question eucalyptus-common eucalyptus/cluster-name string
		;;
	esac

	EUCA_HOME="$(chroot /target getent passwd eucalyptus | cut -f6 -d:)"
	if [ "$EUCA_HOME" ] && [ "${EUCA_HOME#/}" != "$EUCA_HOME" ] && \
	   [ -f "/target$EUCA_HOME/.ssh/id_rsa.pub" ]; then
		PUBKEY="$(cat "/target$EUCA_HOME/.ssh/id_rsa.pub")"
		i=1
		while db_get "eucalyptus/authorized-keys/$i" && [ "$RET" ]; do
			echo "eucalyptus-common	eucalyptus/authorized-keys/$i	string $RET" >>"$OUT"
			i=$(($i + 1))
		done
		echo "eucalyptus-common	eucalyptus/authorized-keys/$i	string $PUBKEY" >>"$OUT"
	fi
}

install_parent_ssh_keys () {
	# Allow SSH authentication by parent components.
	EUCA_HOME="$(chroot /target getent passwd eucalyptus | cut -f6 -d:)"
	if [ "$EUCA_HOME" ] && [ "${EUCA_HOME#/}" != "$EUCA_HOME" ]; then
		i=1
		while db_get "eucalyptus/authorized-keys/$i" && [ "$RET" ]; do
			chroot /target mkdir -m700 -p "$EUCA_HOME/.ssh"
			echo "$RET" >> "/target$EUCA_HOME/.ssh/authorized_keys"
			i=$(($i + 1))
		done
	fi
}

install_ssh_key () {
	# Allow the component's SSH key to authenticate to itself.
	EUCA_HOME="$(chroot /target getent passwd eucalyptus | cut -f6 -d:)"
	if [ "$EUCA_HOME" ] && [ "${EUCA_HOME#/}" != "$EUCA_HOME" ] && \
	   [ -f "/target$EUCA_HOME/.ssh/id_rsa.pub" ]; then
		cat "/target$EUCA_HOME/.ssh/id_rsa.pub" \
			>>"/target/$EUCA_HOME/.ssh/authorized_keys"
	fi
	# Add the host's public keys to its own known_hosts
	if [ -r /target/etc/ssh/ssh_host_rsa_key.pub ]; then
		pubkey=$(cat /target/etc/ssh/ssh_host_rsa_key.pub)
		printf "localhost %s\n" "$pubkey" >> /target/etc/ssh/ssh_known_hosts
		if [ -r /target/etc/hostname ]; then
			hostname=$(cat /target/etc/hostname)
			printf "%s %s\n" "$hostname" "$pubkey" >> /target/etc/ssh/ssh_known_hosts
		fi
	fi
}

set_conf_var () {
	sed -i "s/^\\($1\\)=.*/\\1=\"$2\"/" \
		/target/etc/eucalyptus/eucalyptus.conf
}

configure_interfaces () {
	# Configure the public and private interfaces.

	db_get eucalyptus/public-interface
	public_interface="$RET"
	set_conf_var VNET_PUBINTERFACE "$public_interface" || true

	db_get eucalyptus/private-interface
	private_interface="$RET"
	set_conf_var VNET_PRIVINTERFACE "$private_interface" || true

	if [ "$private_interface" != "$public_interface" ]; then
		cat >> /target/etc/network/interfaces <<EOF

auto $private_interface
iface $private_interface inet dhcp
EOF
	fi
}

get_default_interface () {
	db_get netcfg/choose_interface || return 1
	default_interface="${RET%%:*}"
	# Work around netcfg/choose_interface not always being set:
	#   https://bugs.launchpad.net/ubuntu/+source/netcfg/+bug/430820
	if [ -z "$default_interface" ]; then
		default_interface=eth0
	fi
}

setup_bridge_device () {
	# Set up a bridge device.

	get_default_interface || return
	sed -i "s/^iface $default_interface inet \(.*\)$/iface $default_interface inet manual\n\nauto br0\niface br0 inet \1/" /target/etc/network/interfaces
	cat >> /target/etc/network/interfaces <<EOF
	bridge_ports $default_interface
	bridge_fd 9
	bridge_hello 2
	bridge_maxage 12
	bridge_stp off
EOF
}

install_parent_ssh_keys

db_get eucalyptus/install-mode
components="$(echo "$RET" | sed 's/, */ /g')"
for component in $components; do
	case $component in
	    cloud)
		make_preseed_file $components
		install_ssh_key
		;;
	    cluster)
		make_preseed_file $components
		install_ssh_key
		configure_interfaces
		;;
	    node)
		setup_bridge_device
		;;
	esac
done

exit 0
