#!/bin/bash
###########################################################
# tgz-g5k, a tool to create neutral deployment tgz image
###########################################################
# Copyright (C) 2006 INRIA
# Produced at Institut National de Recherche en Informatique
# Written by Xavier Delaruelle <xavier.delaruelle@loria.fr>
#  
# This file is part of Grid'5000 project.
# For details, see <https://www.grid5000.fr>.
#  
# 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; either version 2
# of the License, or (at your option) any later version.
#
# 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.
###########################################################

# global definitions
USAGE='Usage: tgz-g5k [OPTIONS] [[login@host:]/path/to/image.tgz]'
HELP="$USAGE
tgz-g5k is a tool to create neutral deployment tgz image.

EXAMPLES
  tgz-g5k > /tmp/myimage.tgz
  tgz-g5k /tmp/myimage.tgz
  tgz-g5k frontend:images/myimage.tgz
  tgz-g5k mylogin@frontend:images/myimage.tgz

OPTIONS
  -h, --help                 Show summary of options
  -v, --version              Show version of program"
VERSION='tgz-g5k 1.0.2'
MOUNT=/mnt/root


# retrieve attributes
file='-'
while [ $# -gt 0 ]; do
  case "$1" in
  --help|-h ) echo "$HELP"; exit 0;;
  --version|-v ) echo "$VERSION"; exit 0;;
  -) file=$1; shift;;
  -* ) echo "$USAGE"; exit 1;;
  *) file=$1; shift;;
  esac
done

# check if file pattern is correct
if [ -z "$(echo $file | grep -E '(\w*@)?(\w+:)?.+')" ]; then
  echo "$USAGE"
  exit 1
fi

# need to exclude the archive from itself
if [ "$file" == '-' ]; then
  excludefile=''
elif [ "${file##*:}" == "$file" ]; then
  excludefile="--exclude=${file#/}"
else
  # if remote copy is asked, the script will process in two steps
  # * build the archive locally
  # * copy the built archive to distant host
  remotehost=${file%%:*}
  remotefile=${file##*:}
  file=/tmp/tgz-g5k.tgz
  excludefile="--exclude=${file#/}"
fi


# prepare mount point
[ ! -d $MOUNT ] && mkdir $MOUNT
mount -o bind / $MOUNT

# NOTE: tar's "--file login@host:archive" option cannot be used
# because it does not work if the location of the rmt binary is
# not the same between the distant host and the local host

# NOTE: archive creation must be done in a single pass due to the
# archive output when specified file is stdout (--file -)

# NOTE: The short option "-C" of tar must be used instead of its
# long counterpart "--directory" because of a misterious bug.

# create the archive with the content of /
# but exclude site-specific files or other fingerprint files
# and include their neutral counterpart
tar --numeric-owner --gzip --create \
  --file $file $excludefile \
  --exclude-from=/usr/share/tgz-g5k/dismissed \
  -C $MOUNT \
    $(cd $MOUNT; ls -A) \
  -C /usr/share/tgz-g5k/insipid \
    $(cd /usr/share/tgz-g5k/insipid; ls -A)
# tar returned code will be our own return code
code=$?

# unmount /'s remount
umount $MOUNT


# copy previously well generated archive to distant host if asked
if [ -n "$remotefile" ] && [ $code -eq 0 ]; then
  cat $file | ssh $remotehost cat - ">" $remotefile
  code=$?
  rm -f $file
fi

exit $code
