#!/bin/sh
# vi: ts=4 noexpandtab
#
#    uec-publish-tarball - wrapper for publishing uec tarballs
#
#    Copyright (C) 2010 Canonical Ltd.
#
#    Authors: Scott Moser <smoser@canonical.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, version 3 of the License.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.


TMPD=""
VERBOSITY=1
error() { echo "$@" 1>&2; }
debug() { 
	[ ${VERBOSITY} -ge $1 ] || return 0; 
	shift
	error "$@"
}
log() { debug "$1" "$(date): ====== $2 ======" ; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
cleanup() {
	[ -n "${TMPD}" -a -d "${TMPD}" ] || return 0;
	debug 2 "cleaning up ${TMPD}"
	rm -Rf "${TMPD}";
}
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; exit 1; }
Usage() {
	cat <<EOF
Usage: ${0##*/} [ options ] tarfile bucket [arch]

   register a UEC tarball (ie, per http://uec-images.ubuntu.com)
   if arch is not provided, a name-based attempt is made to guess

   options:
      -k | --kernel  k        use previously registered kernel with id 'k'
                              specify 'none' for no kernel
      -K | --kernel-file f    bundle, upload, use file 'f' as kernel
      -r | --ramdisk r        use previously registered ramdisk with id 'r'
                              specify 'none' for no ramdisk
      -R | --ramdisk-file f   bundle, upload, use file 'f' as ramdisk

           --resize  s        resize the image to 's' bundling uploading
                              's' must be valid input to uec-resize-image
      -q | --quiet            be quiet, only output published ids

   Example:
   - ${0##*/} lucid-uec-i386.tar.gz my-lucid-bucket i386
EOF
}

upload_register() {
	local out="" ret=0
	out=$(uec-publish-image "${@}") || {
		ret=$?
		printf "%s" "${out}"
		return $ret
	}
	set -- ${out}
	_RET=${1}
}


short_opts="hk:K:qr:R:"
long_opts="help,kernel:,kernel-file:,quiet,ramdisk:,ramdisk-file:,resize:"
getopt_out=$(getopt --name "${0##*/}" --shell sh \
	--options "${short_opts}" --long "${long_opts}" -- "$@") &&
	eval set -- "${getopt_out}" ||
	bad_Usage

ramdisk=""
kernel=""
eki=""
eri=""
image=""
emi=""
resize=""

while [ $# -ne 0 ]; do
	cur=${1}; next=${2};
	case "$cur" in
		--) shift; break;;
		-h|--help) Usage; exit 0;;
		-k|--kernel) eki=${next}; shift;;
		-K|--kernel-file)
			[ -f "${next}" ] && kernel=$(readlink -f "${next}") ||
				fail "failed to get path to ${next}"
			shift;;
		-q|--quiet) VERBOSITY=0;;
		-r|--ramdisk) eri=${next}; shift;;
		-R|--ramdisk-file)
			[ -f "${next}" ] && ramdisk=$(readlink -f "${next}") ||
				fail "failed to get path to ${next}"
			shift;;
		--resize) resize=${next}; shift;;
	esac
	shift;
done

tarball=${1}
bucket=${2}
arch=${3}

[ $# -eq 3 -o $# -eq 2 ] || bad_Usage

if [ -z "${arch}" ]; then
	case "${tarball}" in
		*i386*) arch=i386;;
		*amd64*|*x86_64*) arch=amd64;;
		*) fail "unable to guess arch by tarball name. give 3rd arg";;
	esac
fi

[ $arch = "amd64" ] && iarch=x86_64 || iarch=i386

[ -f "${tarball}" ] && tbf=$(readlink -f "${tarball}") ||
	fail "bad tarball: ${tarball}";

# before extracting the tarball, try to verify that the environment
# is set up, by invoking another euca command (LP: #526504)
euca-describe-images >/dev/null ||
	fail "Unable to run euca-describe-images.  Is euca2ools environment set up?"

TMPD=$(mktemp -d ${TEMPDIR:-/tmp}/${0##*/}.XXXXXX) || fail "failed make temp"
trap cleanup EXIT

start=$PWD

cd "${TMPD}"

log 1 "extracting image"
tar -S -xzf "${tbf}" || fail "failed extract ${tarball}"

for x in *; do
	case "$x" in
		*vmlinuz*)
			[ -z "${kernel}" -a -z "${eki}" ] && kernel=${x};;
		*initrd*)
			[ -z "${ramdisk}" -a -z "${eri}" ] && ramdisk=${x};;
		*.img) image=${x};;
	esac
done

[ -z "${image}" ] && fail "can't find image";
[ -n "${kernel}" -o -n "${eki}" ] ||
	bad_Usage "can't find kernel. specify '--kernel none' to register none";
[ -n "${ramdisk}" -o -n "${eri}" ] || {
	debug 1 "Warning: no ramdisk found, assuming '--ramdisk none'"
	eri="none";
}

debug 1 "kernel : ${eki:-${kernel}}"
debug 1 "ramdisk: ${eri:-${ramdisk}}"
debug 1 "image  : ${image##*/}"

if [ -n "${resize}" ]; then
	log 1 "resizing ${image##*/} to ${resize}"
	out=$(uec-resize-image "${image}" "${resize}" 2>&1) || {
		error "${out}";
		fail "failed to resize image file to ${resize}";
	}
fi

if [ -n "${kernel}" ]; then
	log 1 "bundle/upload kernel"
	upload_register --type kernel "${iarch}" "${kernel}" "${bucket}" ||
		fail "failed to upload kernel"
	eki=${_RET}
fi

if [ -n "${ramdisk}" ]; then
	log 1 "bundle/upload ramdisk"
	upload_register --type ramdisk "${iarch}" "${ramdisk}" "${bucket}" ||
		fail "failed ramdisk bundle/upload"
	eri=${_RET}
fi

log 1 "bundle/upload image"
upload_register --type image "${iarch}" "${image}" "${bucket}" \
	--kernel "${eki}" --ramdisk "${eri}" ||
		fail "failed bundle/upload/register of image"
emi=${_RET}

log 1 "done"
printf 'emi="%s"; eri="%s"; eki="%s";\n' "${emi}" "${eri}" "${eki}"
