#!/bin/bash

# Copyright 2014--2016 Jan Pazdziora
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

mark_exit_code () {
	exit_code=$?
	echo $exit_code > /run/ipa/exit_code
	exit $exit_code
}
mkdir -p /run/ipa
trap mark_exit_code ERR EXIT

set -e

test ! -f /run/ipa/debug-trace || set -x

HOSTNAME=$( cat /data/hostname )
IPA_SERVER_IP=
if [ -f /run/ipa/ipa-server-ip ] ; then
	IPA_SERVER_IP=$( cat /run/ipa/ipa-server-ip )
fi

function update_server_ip_address () {
	CURRENT_IP=$( dig +short -t A $HOSTNAME )
	MY_IP=''
	if [ -f /run/ipa/ipa-server-ip ] ; then
		MY_IP=$( cat /run/ipa/ipa-server-ip )
		if [ "$CURRENT_IP" == "$MY_IP" ] ; then
			return
		fi
	else
		for i in $( /sbin/ip addr show | awk '/inet .*global/ { split($2,a,"/"); print a[1]; }' ) ; do
			if [ "$CURRENT_IP" == "$i" ] ; then
				return
			fi
			if [ -z "$MY_IP" ] ; then
				MY_IP="$i"
			fi
		done
	fi

	kdestroy -A
	kinit -k
	(
		echo "update add $HOSTNAME 180 A $MY_IP"
		for i in $CURRENT_IP ; do
			if [ "$i" != "$MY_IP" ] ; then
				echo "update delete $HOSTNAME A $i"
			fi
		done
		echo "send"
		echo "quit"
	) | nsupdate -g
	kdestroy -A

	while true ; do
		NEW_IP=$( dig +short -t A $HOSTNAME )
		if [ "$NEW_IP" == "$MY_IP" ] ; then
			break
		fi
		sleep 1
	done
}

function wait_for_dns () {
	local TIMEOUT="$1"
	local WAIT_UNTIL="$((SECONDS + TIMEOUT))"
	while ! host -t A $HOSTNAME > /dev/null ; do
		if [[ "$SECONDS" -lt "$WAIT_UNTIL" ]]; then
			sleep 1
			continue
		fi
		return 1
	done
        return 0
}

if [ "$1" == update-self-ip-address ] ; then
	exec >> /var/log/ipa-server-run.log 2>&1
	echo "$(date) $0 $@"

	if [ "$IPA_SERVER_IP" == no-update ] ; then
		echo "FreeIPA server IP address update disabled, skipping update-self-ip-address."
	elif systemctl is-active -q named named-pkcs11 || [ -n "$IPA_SERVER_IP" ] ; then
		# Wait until DNS is up and running and resolving
		if wait_for_dns 60; then
			update_server_ip_address
			host $HOSTNAME
		else
			echo "Unable to resolve \"${HOSTNAME}\". Is --dns=127.0.0.1 set for the container?" >&2
			exit 2
		fi
	else
		echo "FreeIPA server does not run DNS server, skipping update-self-ip-address."
	fi
	echo "FreeIPA server started."
	exit
fi

exec >> /var/log/ipa-server-configure-first.log 2>&1

echo "$(date) $0 $@"

function upgrade_server () {
	if [ -x /usr/sbin/setup-ds.pl ] ; then
		/usr/sbin/setup-ds.pl -u -s General.UpdateMode=offline
	fi
	for i in /usr/sbin/ipa-upgrade-rpm-scriptlets* ; do $i 2 ; done
	if [ -f /var/lib/ipa/sysupgrade/sysupgrade.state ] ; then
		PLATFORM=rhel
		if [ -f /etc/fedora-release ] ; then
			PLATFORM=fedora
		fi
		sed -i "s/platform.*/platform = $PLATFORM/" /var/lib/ipa/sysupgrade/sysupgrade.state
	fi
	ipa-server-upgrade
	mv /data/build-id /data/build-id-upgraded-$( date +'%Y%m%d-%H%M%S' )
	cp -f /data-template/build-id /data/build-id
	systemctl default
}

if [ "$1" == upgrade ] ; then
	if ! diff /data/volume-version /etc/volume-version ; then
		echo "The /data volume was created using incompatible image." >&2
		exit 2
	fi
	# Removing kdcinfo.* which is likely to hold old IP address
	rm -rf /var/lib/sss/pubconf/kdcinfo.*
	if cmp /data/build-id /data-template/build-id ; then
		echo "FreeIPA server is already configured, starting the services."
	else
		echo "FreeIPA server is already configured but with different version, starting upgrade."
		# Workaround Lower version of database is expected
		rm -rf /var/lib/sss/db/*
		if [ -f /etc/sysconfig/pki-tomcat ]; then
			for d in /usr/share/java/resteasy* ; do
				sed -i 's#^\(JAVA_OPTS=".*-DRESTEASY_LIB=\)/usr/share/java/resteasy[a-z-]*\(.*"\)#\1'$d'\2#' /etc/sysconfig/pki-tomcat
			done
		fi
		upgrade_server
		echo "FreeIPA server upgraded."
	fi
	exit
fi

set -e

cd /

function usage () {
	if [ -n "$1" ] ; then
		echo $1 >&2
	else
		echo "Start as docker run -h \$FQDN_HOSTNAME -e PASSWORD=\$THE_ADMIN_PASSWORD -v /path:/data:Z image" >&2
	fi
	exit 1
}

if [ -f /etc/ipa/ca.crt ] ; then
	echo "The FreeIPA server was already configured." >&2
	exit 11
else
	COMMAND=ipa-server-install
	RUN_CMD="/usr/sbin/ipa-server-install"
	if [ -f /run/ipa/ipa-replica-install-options ] ; then
		if [ -f /data/ipa-server-install-options ] ; then
			usage "Too many install options files."
		fi
		if [ $(ls /data/ | grep  \\.gpg$ | wc -l) -gt 1 ] ; then
			usage "Too many .gpg files"
		fi
		COMMAND=ipa-replica-install
		RUN_CMD="/usr/sbin/ipa-replica-install"
		if [ -f /data/*.gpg ] ; then
			RUN_CMD="/usr/sbin/ipa-replica-install /data/*.gpg"
		fi
	fi

	(
		cd /data
		grep '/$' /etc/volume-data-list | sed 's!^!.!' | xargs mkdir -p
	)

	HOSTNAME_SHORT=${HOSTNAME%%.*}
	DOMAIN=${HOSTNAME#*.}
	if [ "$HOSTNAME_SHORT.$DOMAIN" != "$HOSTNAME" ] ; then
		usage "The container has to have fully-qualified hostname defined."
	fi

	STDIN=/dev/stdin
	STDOUT=/dev/stdout
	STDERR=/dev/stderr
	if [ -e /dev/console ] && ( test -t 0 ) < /dev/console ; then
		STDIN=/dev/console
		STDOUT=/dev/console
		STDERR=/dev/console
	fi
	if xargs -a <(
		if [ -f /data/$COMMAND-options ] ; then
			cat /data/$COMMAND-options
		fi
		cat /run/ipa/$COMMAND-options
		) $RUN_CMD < $STDIN > $STDOUT 2> $STDERR ; then
		cp /etc/volume-version /data/volume-version

		if ! [ -f /etc/ipa/ca.crt ] && [ -f /root/ipa.csr ] ; then
			cp -p /root/ipa.csr /data/ipa.csr
			echo "FreeIPA CA CSR stored in file ipa.csr located in bind-mounted data volume."
			systemctl poweroff
			exit
		fi
		if [ "$IPA_SERVER_IP" == no-update ] ; then
			echo "FreeIPA server IP address update disabled, skipping update-self-ip-address."
		elif systemctl is-active -q named named-pkcs11 || [ -n "$IPA_SERVER_IP" ] ; then
			if wait_for_dns 180; then
				update_server_ip_address
			else
				echo "Unable to resolve \"${HOSTNAME}\". Is --dns=127.0.0.1 set for the container?" >&2
				exit 2
			fi
		else
			echo "FreeIPA server does not run DNS server, skipping update-self-ip-address."
		fi
		systemctl enable ipa-server-update-self-ip-address.service
		systemctl enable ipa-server-upgrade.service
		systemctl disable ipa-server-configure-first.service || rm -f /etc/systemd/system/multi-user.target.wants/ipa-server-configure-first.service
		echo "FreeIPA server configured."
	else
		ret=$?
		echo "FreeIPA server configuration failed." >&2
		exit $ret
	fi
fi

exit
