#!/bin/bash
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source.  A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#

#
# Copyright (c) 2012, Igor Kozhukhov <ikozhukhov@gmail.com>.  All rights reserved.
#
# VERSION 1.5

#set -x

PATH=/usr/gnu/bin:/usr/bin:/usr/sbin
export PATH

VERBOSE=0
NO_ZONES=0
REPODIR=""
TARGETBE=""
TARGETMOUNT=""
UPGRADE=0

TMPDIR="/tmp/apt.$$"

BEADM="/usr/sbin/beadm"
MKDIR="/usr/bin/mkdir"
BOOTADM="/usr/sbin/bootadm"

LOG="/root/upgrade.log.$$"

TMOUNTED=0

function usage()
{
	echo "Usage:"
	echo "	$0 -t <BE name> -d <path to local APT>"
	echo ""
	echo "Example:"
	echo "	$0 -t nightly-`date +%Y-%m-%d` -d \$PWD/packages/i386/apt"
	exit 0
}

function exit_error()
{
	echo "$*" 2>&1 | tee -a $LOG
	exit 2
}

function do_cmd()
{
	[ $VERBOSE -gt 0 ] && echo "$*" 2>&1 | tee -a $LOG
	eval "$*"
	exit_code=$?
	[ $exit_code -eq 0 ] && return
	exit_error "'$*'" failed: exit code $exit_code
}

function get_mountpoint()
{
	local MNTPOINT=`zfs get -H mountpoint $1 | nawk '{print \$3}'`
	echo $MNTPOINT
}

function is_root_zpool()
{
	local ZROOT=0
	BOOTFS=`zpool get bootfs $1 | grep bootfs | nawk '{print \$3}'`
	if [ "$BOOTFS" = "-" ]; then
	    ZROOT=0
	else
	    ZROOT=1
	fi
	echo $ZROOT
}

###### main ######

while getopts :d:t:R:UvZz i ; do
	case $i in
	d)
		REPODIR="$OPTARG"
		;;
	t)
		TARGETBE="$OPTARG"
		;;
	R)
		TARGETMOUNT="$OPTARG"
		;;
	U)
		UPGRADE=1
		;;
	v)
		VERBOSE=1
		;;
	Z)
		NO_ZONES=1
		;;
	z)
		export ZONEINST=1
		;;
	*)
		usage
	esac
done
shift `expr $OPTIND - 1`

[ -n "$1" ] && usage
[ -z "$TARGETBE" -a -z "$TARGETMOUNT" ] && usage
[ -z "$REPODIR" -a $UPGRADE -lt 1 ] && usage
if [ $UPGRADE -lt 1 -a ! -f "$REPODIR/conf/distributions" ]; then
    echo "Error: Local APT unavailable, please check your path to repo dir: '$REPODIR'"
    exit 1
fi

if [ -z "$TARGETMOUNT" ]; then
    do_cmd mkdir -p "$TMPDIR" 2>&1 | tee -a $LOG
    do_cmd beadm create "$TARGETBE" 2>&1 | tee -a $LOG
    do_cmd beadm mount "$TARGETBE" "$TMPDIR" 2>&1 | tee -a $LOG
else
    TMPDIR="$TARGETMOUNT"
fi

if [ ! -z "$REPODIR" -a -z "$TARGETMOUNT" ]; then
    do_cmd mv /etc/apt/sources.list /etc/apt/sources.list.saved
    echo "deb file://$REPODIR unstable main" > /etc/apt/sources.list
    do_cmd cp -f /etc/apt/sources.list $TMPDIR/etc/apt/sources.list
fi


do_cmd apt-get -R $TMPDIR update 2>&1 | tee -a $LOG
do_cmd apt-get -R $TMPDIR dist-upgrade -y --force-yes 2>&1 | tee -a $LOG

if [ -z "$TARGETMOUNT" ]; then
    do_cmd $BOOTADM update-archive -R $TMPDIR 2>&1 | tee -a $LOG
fi

if [ ! -z "$REPODIR" -a -z "$TARGETMOUNT" ]; then
    do_cmd mv /etc/apt/sources.list.saved /etc/apt/sources.list
    do_cmd cp -f /etc/apt/sources.list $TMPDIR/etc/apt/sources.list
fi

if [ -z "$TARGETMOUNT" ]; then
    do_cmd beadm umount "$TARGETBE" 2>&1 | tee -a $LOG
    do_cmd beadm activate "$TARGETBE" 2>&1 | tee -a $LOG

    echo "Upgrade have been done. Please reboot to new dataset '$TARGETBE'." 2>&1 | tee -a $LOG
    echo "You can find log at: '$LOG'." 2>&1 | tee -a $LOG
else
    echo "Upgrade done.You can find log at: '$LOG'." 2>&1 | tee -a $LOG
fi

exit 0
