#!/bin/sh
#
# $FreeBSD$
#

# PROVIDE: ix-update
# REQUIRE: ix-update-scripts
# BEFORE: middlewared earlykld

. /etc/rc.freenas

readonly UPDATE_FAILED_LOG="/data/update.failed"
HBA_FIRMWARE_UPDATE="/data/.hba_firmware_update"
REBOOT_REQUIRED=0


db_update_real()
{
	export PATH=$PATH:/usr/local/bin:/usr/local/sbin

	echo "Applying database schema changes"

	has_alembic=$(echo "SELECT name FROM sqlite_master WHERE name = 'alembic_version'" | sqlite3 /data/freenas-v1.db)
	if [ "$has_alembic" = "" ];
	then
        /usr/local/sbin/migrate93 -f /data/freenas-v1.db
        NEW_MIGRATION_APPLIED=$(echo "select count(*) from django_migrations where app = 'network' and name = '0007_globalconfiguration_gc_hostname_virtual';" | /usr/local/bin/sqlite3 /data/freenas-v1.db)
        OLD_MIGRATION_APPLIED=$(echo "select count(*) from django_migrations where app = 'network' and name = '0004_auto_20170703_1224';" | /usr/local/bin/sqlite3 /data/freenas-v1.db)
        if [ "$NEW_MIGRATION_APPLIED" -eq "1" -a "$OLD_MIGRATION_APPLIED" -eq "0" ];
        then
            echo "delete from django_migrations where app = 'network' and name = '0007_globalconfiguration_gc_hostname_virtual';" | /usr/local/bin/sqlite3 /data/freenas-v1.db
            echo 'CREATE TABLE "network_globalconfiguration_" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "gc_hostname" varchar(120) NOT NULL, "gc_hostname_b" varchar(120) NULL, "gc_domain" varchar(120) NOT NULL, "gc_ipv4gateway" varchar(42) NOT NULL, "gc_ipv6gateway" varchar(42) NOT NULL, "gc_nameserver1" varchar(42) NOT NULL, "gc_nameserver2" varchar(42) NOT NULL, "gc_nameserver3" varchar(42) NOT NULL, "gc_httpproxy" varchar(255) NOT NULL, "gc_netwait_enabled" bool NOT NULL, "gc_netwait_ip" varchar(300) NOT NULL, "gc_hosts" text NOT NULL);' | /usr/local/bin/sqlite3 /data/freenas-v1.db
            echo "INSERT INTO network_globalconfiguration_ SELECT id, gc_hostname, gc_hostname_b, gc_domain, gc_ipv4gateway, gc_ipv6gateway, gc_nameserver1, gc_nameserver2, gc_nameserver3, gc_httpproxy, gc_netwait_enabled, gc_netwait_ip, gc_hosts FROM network_globalconfiguration;" | /usr/local/bin/sqlite3 /data/freenas-v1.db
            echo "DROP TABLE network_globalconfiguration;" | /usr/local/bin/sqlite3 /data/freenas-v1.db
            echo "ALTER TABLE network_globalconfiguration_ RENAME TO network_globalconfiguration;" | /usr/local/bin/sqlite3 /data/freenas-v1.db
        fi
        /usr/local/sbin/migrate113 -f /data/freenas-v1.db > $UPDATE_FAILED_LOG 2>&1
        if [ $? -ne 0 ]; then
            echo "manage.py migrate failed"
            return 1
        fi
    fi
	/usr/local/sbin/migrate > $UPDATE_FAILED_LOG 2>&1
	if [ $? -ne 0 ]; then
		echo "alembic migrate failed"
		return 1
	fi

	/usr/local/bin/sqlite3 ${FREENAS_CONFIG} "REPLACE INTO system_keyvalue (key, value) VALUES ('run_migration', 'true')"

	rm -f $UPDATE_FAILED_LOG
	return 0
}

handle_error()
{
	local LABELNAME OTHER_PARTNUM PARTNUM TARGET_DRIVE

	echo "Reverting to previous state"

	rm -f $NEED_UPDATE_SENTINEL
	mv ${FREENAS_CONFIG}.bak ${FREENAS_CONFIG}
	if [ -f /data/pwenc_secret.bak ]; then
		mv /data/pwenc_secret.bak /data/pwenc_secret
	fi
	if [ -f $CD_UPGRADE_SENTINEL ]; then
		rm $CD_UPGRADE_SENTINEL
		cat <<EOF
Database upgrade FAILED; check $UPDATE_FAILED_LOG for more details.
Reverting a failed CD upgrade is not totally possible
Rebooting in 15 seconds..
EOF
		sleep 15
		reboot
	fi

	cat <<EOF
Database upgrade FAILED; check $UPDATE_FAILED_LOG for more details.
Rebooting in 15 seconds..
EOF
	sleep 15
	reboot
}

db_update()
{
	if [ -f ${HBA_FIRMWARE_UPDATE} ]; then
		mount -uw /
		if [ -f /usr/local/sbin/firmware_update.py ]; then
			LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/python /usr/local/sbin/firmware_update.py
			if [ $? -eq 0 ]; then
				# Users often wonder why a 3rd reboot occurs on their system
				# when they upgrade their box. This is the reason why.
				# To keep the long, drawn out story as short as possible
				# and to maintain the fickle state that my mind is in
				# after troubleshooting upgrade code for an entire day,
				# /update-scripts gets created on upgrade by default
				# in the Installer.py code (freenas-update).
				# ix-update-scripts runs before this script and reboots
				# the box before this rc script gets called.
				# So a 2nd reboot occurs, and if the system that is being
				# upgraded also has a SAS HBA card that received a
				# firmware upgrade, then we set this variable to 1. As
				# you may already guess, a 3rd reboot occurs. This will
				# make you drink, if you don't already and/or step away
				# from the computer and make you question your life choices.
				REBOOT_REQUIRED=1
			fi
		else
			# The auto firmware update tool is only in TrueNAS
			# FreeNAS users will mostly be happy that FreeNAS doesn't
			# muck with their HBA firmware...because the chance of bricking
			# a random card is a non-zero number.  (Besides, tracking down
			# the firmware for every embedded Avago card out there is not
			# realistic.)
			rm ${HBA_FIRMWARE_UPDATE}
		fi
	fi
			
	if [ ! -f $NEED_UPDATE_SENTINEL ]; then
		if [ ${REBOOT_REQUIRED} -eq 1 ]; then
			reboot
		fi
		# exit this script and continue with normal boot.
		exit 0
	fi

	# We are running very early, make / read-write.
	mount -uw /
	echo "Saving current ${FREENAS_CONFIG} to ${FREENAS_CONFIG}.bak"
	cp ${FREENAS_CONFIG} ${FREENAS_CONFIG}.bak

	is_upload=0
	if [ -f /data/uploaded.db ]; then
		echo "Moving uploaded config to ${FREENAS_CONFIG}"
		mv /data/uploaded.db ${FREENAS_CONFIG}
		if [ -f /data/pwenc_secret_uploaded ]; then
			if [ -f /data/pwenc_secret ]; then
				echo "Saving current pwenc secret to /data/pwenc_secret.bak"
				cp /data/pwenc_secret /data/pwenc_secret.bak
			fi
			echo "Moving uploaded pwenc secret to /data/pwenc_secret"
			mv /data/pwenc_secret_uploaded /data/pwenc_secret
		fi
		is_upload=1
	fi

	set +e
	db_update_real || handle_error
	set -e

	if [ $is_upload -eq 1 ]; then
		/usr/local/bin/sqlite3 ${FREENAS_CONFIG} "REPLACE INTO system_keyvalue (key, value) VALUES ('run_migration', 'true')"
		/usr/local/bin/sqlite3 ${FREENAS_CONFIG} "UPDATE system_update SET upd_train = ''"
	fi

	rm -f $NEED_UPDATE_SENTINEL
	rm -f $CD_UPGRADE_SENTINEL

	echo "Database upgrade complete.  Rebooting."
	cd /
	sleep 2
	reboot
}

name="ix_update"
start_cmd='db_update'
stop_cmd=':'

load_rc_config $name
run_rc_command "$1"
