#!/bin/sh

set -e
set -x

if ! [ -r /etc/openstack-cluster-installer/openstack-cluster-installer.conf ] ; then
	echo "Could not load /etc/openstack-cluster-installer/openstack-cluster-installer.conf"
	exit 1
else
	TMPFILE=$(mktemp -t openstack-cluster-installer.XXXXXX)
	cat /etc/openstack-cluster-installer/openstack-cluster-installer.conf | grep -v '^\[' >${TMPFILE}
	. ${TMPFILE}
	rm ${TMPFILE}
fi

if [ -x ./openstack-cluster-installer-build-live-image-clean ] ; then
	./openstack-cluster-installer-build-live-image-clean
else
	openstack-cluster-installer-build-live-image-clean
fi

for i in $@ ; do
	case "${1}" in
	"--pxe-server-ip")
		if [ -z "${2}" ] ; then echo "Parameter for option --pxe-server-ip is missing" > /dev/stderr ; DO_EXIT="yes" ; fi
		OTCI_PXE_SERVER_IP=${2}
		shift
		shift
		;;
	"--debian-mirror-addr")
		if [ -z "${2}" ] ; then echo "Parameter for option --debian-mirror-addr is missing" > /dev/stderr ; DO_EXIT="yes" ; fi
		OTCI_DEB_MIRROR_ADDR=${2}
		shift
		shift
		;;
	"--debian-security-mirror-addr")
		if [ -z "${2}" ] ; then echo "Parameter for option --debian-mirror-addr is missing" > /dev/stderr ; DO_EXIT="yes" ; fi
		OTCI_DEB_SECURITY_MIRROR_ADDR=${2}
		shift
		shift
	;;
	*)
		;;
	esac
done
if [ -z "${OTCI_PXE_SERVER_IP}" ] ; then
	DEFROUTE_IF=`awk '{ if ( $2 == "00000000" ) print $1 }' /proc/net/route`
	if [ -n "${DEFROUTE_IF}" ] ; then
		if [ -x /bin/ip ] ; then
			DEFROUTE_IP=`LC_ALL=C ip addr show "${DEFROUTE_IF}" | grep inet | head -n 1 | awk '{print $2}' | cut -d/ -f1 | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'`
		else
			DEFROUTE_IP=`hostname -i | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'`
		fi
	fi
	if [ -n "${DEFROUTE_IP}" ] ; then
		OTCI_PXE_SERVER_IP=${DEFROUTE_IP}
	else
		OTCI_PXE_SERVER_IP=$(ipcalc ${OPENSTACK_CLUSTER_NETWORK} | grep HostMin | awk '{print $2}')
	fi
        echo "No --pxe-server-ip given, using ${OTCI_PXE_SERVER_IP} as default." > /dev/stderr
        OTCI_PXE_SERVER_IP=${OTCI_PXE_SERVER_IP}
fi

if [ "${DO_EXIT}" = "yes" ] ; then
	echo "Parameters not validated: will exit now!" > /dev/stderr
	echo "Example call: $0 --pxe-server-ip ${OTCI_PXE_SERVER_IP} --debian-mirror-addr http://${OTCI_PXE_SERVER_IP}:9999/debian" > /dev/stderr
	exit 1
fi

# Manage ssh keys
if [ -e /etc/openstack-cluster-installer/id_rsa.pub ] ; then
	echo "Will use existing /etc/openstack-cluster-installer/id_rsa.pub file"
else
	echo "No ssh key found, generating one"
	ssh-keygen -b 4096 -t rsa -f /etc/openstack-cluster-installer/id_rsa -q -N ""
fi
if ! [ -e /etc/openstack-cluster-installer/authorized_keys ] ; then
	cat /etc/openstack-cluster-installer/id_rsa.pub >/etc/openstack-cluster-installer/authorized_keys
	if [ -e /root/.ssh/authorized_keys ] ; then
		cat /root/.ssh/authorized_keys >>/etc/openstack-cluster-installer/authorized_keys
	fi
	chown www-data:www-data /etc/openstack-cluster-installer/id_rsa*
fi

mkdir -p config/includes.chroot/root/.ssh/
chmod 700 config/includes.chroot/root/.ssh/
cp /etc/openstack-cluster-installer/authorized_keys config/includes.chroot/root/.ssh/authorized_keys
chmod 600 config/includes.chroot/root/.ssh/authorized_keys

# Add our repository with updated openstack-debian-images and lshw
mkdir -p config/archives/
echo "deb http://stretch-queens.debian.net/debian stretch-queens-backports main
deb http://stretch-queens.debian.net/debian stretch-queens-backports-nochange main
" >config/archives/stretch-queens.list.chroot
cp /etc/openstack-cluster-installer/pubkey.gpg config/archives/stretch-queens.key.chroot

echo "deb ${OTCI_DEB_MIRROR_ADDR} stretch contrib non-free
deb-src ${OTCI_DEB_MIRROR_ADDR} stretch contrib non-free
" >config/archives/contrib-non-free.list.chroot

# Copy the agent
mkdir -p config/includes.chroot/usr/bin
cp /usr/bin/openstack-cluster-installer-agent config/includes.chroot/usr/bin
sed -i s/__OCI__GATEWAY__REPLACE__ME__/${OTCI_PXE_SERVER_IP}/ config/includes.chroot/usr/bin/openstack-cluster-installer-agent

# Add the IP of the PXE server in a configuration file
# for later use during the install process
mkdir -p config/includes.chroot/etc/oci
echo ${OTCI_PXE_SERVER_IP} >config/includes.chroot/etc/oci/pxe-server-ip

mkdir -p config/includes.chroot/etc
echo "#!/bin/sh

set -e

# Start the thing once...
/usr/bin/openstack-cluster-installer-agent

# Set status = live
PXE_SERVER_IP=\$(cat /etc/oci/pxe-server-ip)
CHASSIS_SERIAL=\$(dmidecode -s chassis-serial-number)

curl \"http://\${PXE_SERVER_IP}/oci/install-status.php?status=live&chassis-serial=\${CHASSIS_SERIAL}\"

# Install the daemon
update-rc.d oci-agent-daemon defaults
/etc/init.d/oci-agent-daemon start

exit 0
" >config/includes.chroot/etc/rc.local
chmod +x config/includes.chroot/etc/rc.local

# Install it in crontab
mkdir -p config/includes.chroot/etc/init.d
echo "#!/bin/sh

### BEGIN INIT INFO
# Provides:          oci-agent-daemon
# Required-Start:    \$network
# Required-Stop:     \$network
# Should-Start:      \$local_fs
# Should-Stop:       \$local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: A small daemon to report slave nodes
# Description:       A small script to report slave nodes
### END INIT INFO

DESC=\"OpenStack cluster installer agent daemon (oci-agent-daemon)\"
NAME=oci-agent-daemon
DAEMON=/usr/bin/\${NAME}
PIDFILE=/var/run/oci-agent-daemon.pid
DAEMON=/usr/bin/oci-agent-daemon

. /lib/lsb/init-functions

do_start() {
	start-stop-daemon \\
		--start \\
		--quiet \\
		--background \\
		--make-pidfile --pidfile \${PIDFILE} \\
		--startas \$DAEMON \\
		--test > /dev/null \\
		|| return 1
	start-stop-daemon \\
		--start \\
		--quiet \\
		--background \\
		--make-pidfile --pidfile \${PIDFILE} \\
		--startas \$DAEMON \\
		|| return 2
}

do_stop() {
	start-stop-daemon \\
		--stop \\
		--quiet \\
		--retry=TERM/30/KILL/5 \\
		--pidfile \$PIDFILE
	RETVAL=\$?
	rm -f \$PIDFILE
	return \"\$RETVAL\"
}

do_systemd_start() {
	exec \$DAEMON
}

case \"\$1\" in
start|systemd-start)
	log_daemon_msg \"Starting \$DESC\" \"\$NAME\"
	do_start
	case \$? in
		0|1) log_end_msg 0 ; RET=\$? ;;
		2)   log_end_msg 1 ; RET=\$? ;;
		esac
;;
stop)
	log_daemon_msg \"Stopping \$DESC\" \"\$NAME\"
	do_stop
	case \$? in
		0|1) log_end_msg 0 ; RET=\$? ;;
		2)   log_end_msg 1 ; RET=\$? ;;
        esac
;;
restart|reload|force-reload)
        \$0 stop
        sleep 1
        \$0 start
;;
*)
        echo 'Usage: \$0 {start|stop|restart|reload}'
        exit 1
;;
esac

exit 0
" >config/includes.chroot/etc/init.d/oci-agent-daemon
chmod +x config/includes.chroot/etc/init.d/oci-agent-daemon

mkdir -p /usr/bin
echo "#!/bin/sh

set -e

# Contact PXE server once, anytime, during this interval
INTERVAL=30
while [ 1 ] ; do
	DELAY=\$((  \$(dd if=/dev/urandom bs=512 count=1 2>&1 | cksum | cut -d' ' -f1) % \${INTERVAL} ))
	END_COMMAND=\$(( \${INTERVAL} - \${DELAY} ))
	sleep \${DELAY}
	/usr/bin/openstack-cluster-installer-agent
	sleep \${END_COMMAND}
done

" >config/includes.chroot/usr/bin/oci-agent-daemon
chmod +x config/includes.chroot/usr/bin/oci-agent-daemon

echo "#!/bin/sh

set -e

PXE_SERVER_IP=\$(cat /etc/oci/pxe-server-ip)

curl http://\${PXE_SERVER_IP}/oci/install-status.php?status=installing
if ! build-openstack-debian-image \$@ --pre-reboot-hook /usr/bin/oci-install-pre-reboot-hook ; then
	# TODO: Report this as failed OS install
	curl http://\${PXE_SERVER_IP}/oci/install-status.php?status=live
fi
" >config/includes.chroot/usr/bin/oci-install-with-report
chmod +x config/includes.chroot/usr/bin/oci-install-with-report

echo "#!/bin/sh

set -e

PXE_SERVER_IP=\$(cat /etc/oci/pxe-server-ip)

curl http://\${PXE_SERVER_IP}/oci/install-status.php?status=firstboot
" >config/includes.chroot/usr/bin/oci-install-pre-reboot-hook
chmod +x config/includes.chroot/usr/bin/oci-install-pre-reboot-hook

cp /usr/bin/openstack-cluster-installer-bodi-hook-script config/includes.chroot/usr/bin

mkdir -p config/includes.chroot/etc/network
echo "auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp" >config/includes.chroot/etc/network/interfaces

mkdir -p config/package-lists
echo "bc
bind9-host
curl
dmidecode
debootstrap
dosfstools
extlinux
firmware-bnx2
firmware-bnx2x
ipcalc
ipmitool
joe
jq
kbd
kpartx
lshw
mbr
net-tools
nmap
ntp
openssh-server
openssh-client
openstack-debian-images
openstack-pkg-tools
parted
pciutils
policykit-1
qemu-utils
syslinux-common
tcpdump
util-linux
wget" > config/package-lists/openstack.list.chroot

cp -auxf /usr/share/live/build/bootloaders config
	
lb clean
lb config --mirror-binary http://${OTCI_PXE_SERVER_IP}:9999/debian -b netboot --bootappend-live "boot=live systemd.show_status=true biosdevname=0 net.ifnames=0 components url=http://${OTCI_PXE_SERVER_IP} fetch=http://${OTCI_PXE_SERVER_IP}/openstack-cluster-installer/filesystem.squashfs" --net-root-path /var/lib/openstack-cluster-installer --net-root-server ${OTCI_PXE_SERVER_IP}

# Change the default mirror in the config
if [ -n "${OTCI_DEB_MIRROR_ADDR}" ] ; then
	for i in LB_PARENT_MIRROR_BOOTSTRAP LB_PARENT_MIRROR_CHROOT LB_PARENT_MIRROR_DEBIAN_INSTALLER LB_MIRROR_BOOTSTRAP LB_MIRROR_CHROOT LB_MIRROR_DEBIAN_INSTALLER \
		LB_PARENT_MIRROR_BINARY LB_MIRROR_BINARY ; do
		sed -i 's|^'${i}'=.*|'${i}'="'${OTCI_DEB_MIRROR_ADDR}'"|' config/bootstrap
	done
fi

# Change the default security mirror in the config
if [ -n "${OTCI_DEB_SECURITY_MIRROR_ADDR}" ] ; then
	for i in LB_PARENT_MIRROR_CHROOT_SECURITY LB_PARENT_MIRROR_BINARY_SECURITY LB_MIRROR_CHROOT_SECURITY LB_MIRROR_BINARY_SECURITY ; do
		sed -i 's|^'${i}'=.*|'${i}'="'${OTCI_DEB_SECURITY_MIRROR_ADDR}'"|' config/bootstrap
	done
fi

sed -i 's/^LB_BOOTLOADERS=.*/LB_BOOTLOADERS="syslinux"/' config/binary

# Fix the default syslinux timeout to 5 seconds
sed -i "s/timeout 0/timeout 5/" config/bootloaders/isolinux/isolinux.cfg
sed -i "s/timeout 0/timeout 5/" config/bootloaders/pxelinux/pxelinux.cfg/default
sed -i "s/timeout 0/timeout 5/" config/bootloaders/syslinux/syslinux.cfg
sed -i "s/timeout 0/timeout 5/" config/bootloaders/extlinux/extlinux.conf

sed -i s/ftp.debian.org/${OTCI_PXE_SERVER_IP}:9999/ config/bootstrap

lb build

# Copy the tftp stuff
mkdir -p /var/lib/openstack-cluster-installer/tftp
cp -r tftpboot/* /var/lib/openstack-cluster-installer/tftp
mkdir -p /var/lib/openstack-cluster-installer/tftp/live
cp -auxf tftpboot/live/vmlinuz* tftpboot/live/initrd* /var/lib/openstack-cluster-installer/tftp/live
cp binary/live/filesystem.squashfs /var/lib/openstack-cluster-installer

# Create the ipxe-boot-script, needed for ipxe support.
echo "#!ipxe

chain tftp://${OTCI_PXE_SERVER_IP}/lpxelinux.0
" > /var/lib/openstack-cluster-installer/tftp/ipxe-boot-script

cp /usr/lib/PXELINUX/lpxelinux.0 /var/lib/openstack-cluster-installer/tftp

# dhcptd.conf must have something like this:
#subnet 192.168.111.0 netmask 255.255.255.0 {
#  range 192.168.111.2 192.168.111.2;
#  option routers 192.168.111.1;
#  next-server 192.168.111.1;
#  if exists user-class and option user-class = "iPXE" {
#    filename "http://192.168.111.1/openstack-cluster-installer/tftp/ipxe-boot-script";
#  } else {
#    filename "pxelinux.0";
#  }
#}
#
#host cluster-installer.debian.net { hardware ethernet 08:00:27:06:CC:DF; fixed-address 192.168.111.2; }
