#!/bin/sh
# copyright (C) 2014 FUJITSU LIMITED All Rights Reserved

# 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 2
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
# 02110-1301, USA.

VAL_PREFIX="/opt/lxcf"

# check root
if [ ${EUID:-${UID}} != 0 ]; then
    echo "error: Because you are not root, you cannot execute this command. "
    exit 1
fi

# check options
FLG_N=0 ; VAL_NAME=""
FLG_P=0 ; FILEPATH=""
FLG_F=0 
FLG_S=0 

while getopts n:p:fs OPT ; do
  case $OPT in
  n) FLG_N=1 ; VAL_NAME=$OPTARG ;;
  p) FLG_P=1 ; FILEPATH=$OPTARG ;;
  f) FLG_F=1 ;;
  s) FLG_S=1 ;;
  esac
done
shift $((OPTIND - 1))

# check args
if [ $# -ne 1 ]; then
	echo "usage: lxcf restore [ -n NEW_NAME ] [ -p PATH ] [ -f ] [ -s ] SNAPSHOT_IMAGE"
	exit 1
fi

if [ $FLG_P -eq 1 ]; then
	if ! /usr/lib64/lxcf/lxcf-parmchk-cname $VAL_NAME ; then
	  echo "error:" $VAL_NAME "is not a container name"
	  echo "        The container name must be alphanumeric character, \"-\", and \"_\"."
	  exit 1
	fi
fi

# check /opt/lxcf
mkdir -p /opt/lxcf

# check /etc/lxcf/rsc
mkdir -p /etc/lxcf/rsc

# check lxcf.conf
if [ ! -e /etc/lxcf/lxcf.conf ] ; then
  cp -p /usr/lib64/lxcf/lxcf.conf /etc/lxcf/lxcf.conf
fi

# check /etc/hosts
if [ ! -e /etc/hosts ] ; then
   echo "127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4" > /etc/hosts
   echo "::1         localhost localhost.localdomain localhost6 localhost6.localdomain6" >> /etc/hosts
fi

# check -p path
if [ ${FLG_P} -eq 1 ] ; then
  if [ ! -d $FILEPATH ] ; then
    echo "error:" $FILEPATH "is not a directory"
    exit 1
  fi
  if echo $FILEPATH | grep "^/opt/lxcf" ; then
    echo "error:" $FILEPATH "overlaps with passing other containers. "
    echo "      " $FILEPATH "contains /opt/lxcf."
    exit 1
  fi
  for i in /opt/lxcf/*
  do
    apath=`readlink -f $i`
    if echo $FILEPATH | grep "^${apath}" ; then
      echo "error:" $FILEPATH "overlaps with passing other containers. "
      echo "      " $FILEPATH "contains $apath."
      exit 1
    fi
  done
fi

if [ ! -e $1 ]; then
	echo "error : The specified image does not exist:" $1
	exit 1
fi

CONTPATH=${1%/*}
if [ $CONTPATH == $1 ]; then
	CONTPATH=$PWD
fi
CONTPATH=`cd ${CONTPATH};pwd`

IMAGE=`basename $1 ".img"`

if [ ${#IMAGE} -lt 38 ]; then
	echo "error : The length of Image name is abnormal"
	exit 1
fi

LXCF_UUID=`echo $IMAGE | cut -c -36 `
LXCNAME=`echo $IMAGE | cut -c 38- `

if [ $FLG_N -eq 1 -a x$LXCNAME == x$VAL_NAME ]; then
	FLG_N=0
	VAL_NAME=""
fi

lsdir() {
  ls -f --ind=none $1 | sed '/^\.\{1,2\}$/d'
}

# check existing LXCNAME and UUID
if [ $FLG_F -eq 0 -a $FLG_N -eq 0 ]; then
	for i in `lsdir /etc/lxcf/rsc`
	do
		if [ x$i == x".work" ]; then
			continue;
		fi
		if [ x${i} == x${LXCNAME} -o x${LXCF_UUID} == x`cat /etc/lxcf/rsc/${i}/uuid` ]; then
			echo "error : There is a container of the same name:" $LXCNAME ":" $LXCF_UUID
			exit 1
		fi
	done
elif [ $FLG_F -eq 0 -a $FLG_N -eq 1 ]; then
	for i in `lsdir /etc/lxcf/rsc`
	do
		if [ x${i} == x${VAL_NAME} ]; then
			echo "error : There is a container of the same name:" $VAL_NAME 
			exit 1
		fi
	done
elif [ $FLG_F -eq 1 -a $FLG_N -eq 0 ]; then
	for i in `lsdir /etc/lxcf/rsc`
	do
		if [ x$i == x".work" ]; then
			continue;
		fi
		if [ x${i} == x${LXCNAME} -o x${LXCF_UUID} == x`cat /etc/lxcf/rsc/${i}/uuid` ]; then
			/usr/sbin/lxcf erase $i >& /dev/null
		fi
	done
elif [ $FLG_F -eq 1 -a $FLG_N -eq 1 ]; then
	for i in `lsdir /etc/lxcf/rsc`
	do
		if [ x$i == x".work" ]; then
			continue;
		fi
		if [ x${i} == x${VAL_NAME} -o x${LXCF_UUID} == x`cat /etc/lxcf/rsc/${i}/uuid` ]; then
			/usr/sbin/lxcf erase $i >& /dev/null
		fi
	done
fi

# check -p path
if [ ${FLG_P} -eq 1 ] ; then
  if [ ! -d $FILEPATH ] ; then
    echo "error:" $FILEPATH "is not a directory"
    exit 1
  fi
  if echo $FILEPATH | grep "^/opt/lxcf" ; then
    echo "error:" $FILEPATH "overlaps with passing other containers. "
    echo "      " $FILEPATH "contains /opt/lxcf."
    exit 1
  fi
  for i in /opt/lxcf/*
  do
    apath=`readlink -f $i`
    if echo $FILEPATH | grep "^${apath}" ; then
      echo "error:" $FILEPATH "overlaps with passing other containers. "
      echo "      " $FILEPATH "contains $apath."
      exit 1
    fi
  done
fi

# Decompression of image
cd $CONTPATH
tar xzf ${IMAGE}.img

# check UUID
IMAGEUUID=`tar tzf ${IMAGE}.img | head -1`
if [ ! -f ${IMAGEUUID}$LXCNAME/uuid ]; then
    echo "error: snapshot image is abnormal"
    rm -rf $IMAGEUUID
    exit 1
fi
FILEUUID=`cat ${IMAGEUUID}$LXCNAME/uuid`
if [ x${LXCF_UUID}/ != x${IMAGEUUID} -o x${LXCF_UUID} != x${FILEUUID} ]; then
    echo "error: UUID of snapshot is abnormal:" $LXCF_UUID
    rm -rf $IMAGEUUID
    exit 1
fi
 
# check container name
if [ ! -f ${IMAGEUUID}/name ]; then
    echo "error: snapshot image is abnormal"
    rm -rf $IMAGEUUID
    exit 1
fi
FILELXCNAME=`cat ${IMAGEUUID}/name`
if [ x${LXCNAME} != x${FILELXCNAME} ]; then
    echo "error: UUID of sngapshot is abnormal:" $LXCNAME
    rm -rf $IMAGEUUID
    exit 1
fi

# when -n is specified, change $LXCNAME to $VAL_NAME
if [ $FLG_N -eq 0 ]; then
	# set symbolic link for -p option
	if [ $FLG_P -eq 1 ] ; then
	    mkdir -p ${FILEPATH}
	    tar xzf ${CONTPATH}/${LXCF_UUID}/snapshot.tgz -C ${FILEPATH}
	    ln -s  ${FILEPATH}/${LXCNAME}  ${VAL_PREFIX}/${LXCNAME}
	else
	    mkdir -p /opt/lxcf
	    tar xzf ${CONTPATH}/${LXCF_UUID}/snapshot.tgz -C /opt/lxcf
	fi

	cp -pr ${CONTPATH}/${LXCF_UUID}/${LXCNAME} /etc/lxcf/rsc/.

else
	# set symbolic link for -p option
	if [ $FLG_P -eq 1 ] ; then
	    mkdir -p ${FILEPATH}/${VAL_NAME}
	    tar xzf ${CONTPATH}/${LXCF_UUID}/snapshot.tgz \
		-C ${FILEPATH}/${VAL_NAME} --strip-components=1
	    ln -s  ${FILEPATH}/${VAL_NAME}  ${VAL_PREFIX}/${VAL_NAME}
	else
	    mkdir -p /opt/lxcf/${VAL_NAME}
	    tar xzf ${CONTPATH}/${LXCF_UUID}/snapshot.tgz \
		-C /opt/lxcf/${VAL_NAME} --strip-components=1
	fi

	mv ${CONTPATH}/${LXCF_UUID}/${LXCNAME} \
		${CONTPATH}/${LXCF_UUID}/${VAL_NAME}
	mv ${CONTPATH}/${LXCF_UUID}/${VAL_NAME}/${LXCNAME}.xml \
		${CONTPATH}/${LXCF_UUID}/${VAL_NAME}/${VAL_NAME}.xml	
	cp -pr ${CONTPATH}/${LXCF_UUID}/${VAL_NAME} /etc/lxcf/rsc/.

	sed -i "s/${LXCNAME}/${VAL_NAME}/" /etc/lxcf/rsc/${VAL_NAME}/${VAL_NAME}.xml
	sed -i "/<uuid>/d" /etc/lxcf/rsc/${VAL_NAME}/${VAL_NAME}.xml
	sed -i "s/${LXCNAME}/${VAL_NAME}/g" /etc/lxcf/rsc/${VAL_NAME}/resource.val
	CMODE=`awk '{print $2}' /etc/lxcf/rsc/${LXCNAME}/container_name`
	echo -n $VAL_NAME $CMODE > /etc/lxcf/rsc/$VAL_NAME/container_name
	cp -p /etc/lxcf/rsc/$VAL_NAME/container_name \
		/opt/lxcf/$VAL_NAME/etc/lxcf/container_name 
	NEW_UUID=`uuidgen -t`
	echo -n ${NEW_UUID} > /etc/lxcf/rsc/${VAL_NAME}/uuid

	LXCNAME=$VAL_NAME
	OLD_UUID=$LXCF_UUID
	LXCF_UUID=$NEW_UUID
fi

# The lack package is added. 
if [ $FLG_S -eq 1 ]; then
	LANG=C yum list installed |  \
		awk 'BEGIN{f=0}{if(f==1)print $1;if($1=="Installed")f=1}' \
			> ${CONTPATH}/${LXCF_UUID}/pkg.info_host
	diff -u ${CONTPATH}/${LXCF_UUID}/pkg.info_host \
		${CONTPATH}/${LXCF_UUID}/pkg.info \
	| egrep -v '\+\+' | egrep '^\+' | sed 's/^+//'  \
	| awk '{yumcmd="lxcf update yum install -y " $1 ";wait";system(yumcmd)}'
fi

# erase temporary directory
if [ $FLG_N -eq 0 ]; then
	rm -rf ${CONTPATH}/${LXCF_UUID}
else
	rm -rf ${CONTPATH}/${OLD_UUID}
fi

# create hostname
echo ${LXCNAME} > ${VAL_PREFIX}/${LXCNAME}/etc/hostname

# clone ip address
/usr/lib64/lxcf/lxcf-clone-setup ${LXCNAME}

# create authorized_keys
mkdir -p ${VAL_PREFIX}/${LXCNAME}/root/.ssh
chmod 700 ${VAL_PREFIX}/${LXCNAME}/root/.ssh
cp /root/.ssh/lxcf_rsa.pub ${VAL_PREFIX}/${LXCNAME}/root/.ssh/authorized_keys
chmod 600 ${VAL_PREFIX}/${LXCNAME}/root/.ssh/authorized_keys

/usr/lib64/lxcf/lxcf-define $LXCNAME

# check autostart mode
if [ -e /etc/lxcf/rsc/$LXCNAME/autostart ]; then
	/usr/sbin/lxcf autostart $LXCNAME
fi

echo "restored" $LXCNAME:$LXCF_UUID
/usr/lib64/lxcf/lxcf-start $LXCNAME

exit 0

