#!/bin/sh
# copyright (C) 2013-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.

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

umask 022

# check options
FLG_P=0
FILEPATH=""

while getopts sjc:p: OPT
do
  case $OPT in
    "p" ) FLG_P=1 ; FILEPATH=$OPTARG ;;
  esac
done

shift `expr $OPTIND - 1`

# check args
if [ $# -lt 2 ]; then
	echo "usage: lxcf clone SRC-LXCNAME DIST-LXCNAME"
	exit 1
fi

# args and environment variables
BASENAME=${1}
VAL_PREFIX="/opt/lxcf"

shift 1

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

if ! [ -e /opt/lxcf/${BASENAME} ] ; then
  echo 'error: cannot find' $BASENAME
  exit -1
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

# check model
model=`awk '{print $2}' /opt/lxcf/${BASENAME}/etc/lxcf/container_name`

# cp files
cpfiles() {

  for i in $1/*
  do
    dir=`basename $i`
    if [ x$dir == x"dev" -o x$dir == x"proc" -o x$dir == x"run" \
		-o x$dir == x"sys" ] ; then
      continue;
    fi
    if [ x$dir == x"usr" ] ; then
      if [ x$model == x"joint" ] ; then
        continue
      fi
    fi

    cp -a $i $2/.
    echo "create" $dir
  done
  mkdir -p $2/dev $2/proc $2/run $2/sys
}

# clone one container
lxcf_clone1() {
  LXCNAME=${1}

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

  # check LXCNAME
  if [ -e /${VAL_PREFIX}/${LXCNAME}/etc/lxcf/rsc/${LXCNAME} ] ; then
	echo "error: There is already " ${LXCNAME}
	exit 1
  fi

  trap '/usr/lib64/lxcf/lxcf-erase ${LXCNAME};exit 1' 2

  # new container dir
  mkdir -p /etc/lxcf/rsc/${LXCNAME}

  # set uuid
  # UUID of queue is passed, if clone is called from job
  if [ x$UUID = x"" ]; then
    UUID=`uuidgen -t`
  fi
  echo -n ${UUID} > /etc/lxcf/rsc/${LXCNAME}/uuid
  UUID=""

  echo "create "${VAL_PREFIX}/${LXCNAME}
  mkdir -p ${VAL_PREFIX}/${LXCNAME}

  # copy source dir to dist dir
  #rsync -al --inplace  ${VAL_PREFIX}/${BASENAME}/ ${VAL_PREFIX}/${LXCNAME}
  rm -rf ${VAL_PREFIX}/${LXCNAME}

  # set symbolic link for -p option
  if [ $FLG_P -eq 1 ] ; then
    mkdir -p ${FILEPATH}/${LXCNAME}
    cpfiles ${VAL_PREFIX}/${BASENAME} ${FILEPATH}/${LXCNAME}
    ln -s  ${FILEPATH}/${LXCNAME}  ${VAL_PREFIX}/${LXCNAME}
  else
    mkdir -p ${VAL_PREFIX}/${LXCNAME}
    cpfiles ${VAL_PREFIX}/${BASENAME} ${VAL_PREFIX}/${LXCNAME}
  fi

  mkdir -p ${VAL_PREFIX}/${LXCNAME}/usr
  mkdir -p ${VAL_PREFIX}/${LXCNAME}/opt

  # create xml file
  rm -rf /etc/lxcf/rsc/${LXCNAME}
  cp -pr /etc/lxcf/rsc/${BASENAME} /etc/lxcf/rsc/${LXCNAME}
  mv /etc/lxcf/rsc/${LXCNAME}/${BASENAME}.xml /etc/lxcf/rsc/${LXCNAME}/${LXCNAME}.xml
  sed -i "s/${BASENAME}/${LXCNAME}/" /etc/lxcf/rsc/${LXCNAME}/${LXCNAME}.xml
  sed -i "/<uuid>/d" /etc/lxcf/rsc/${LXCNAME}/${LXCNAME}.xml

  # create resource.val file
  cp -p /etc/lxcf/rsc/${BASENAME}/resource.val /etc/lxcf/rsc/${LXCNAME}/.
  sed -i "s/${BASENAME}/${LXCNAME}/g" /etc/lxcf/rsc/${LXCNAME}/resource.val

  # create container_name
  cp -p /opt/lxcf/${BASENAME}/etc/lxcf/container_name /opt/lxcf/${LXCNAME}/etc/lxcf/container_name
  sed -i "s/${BASENAME}/${LXCNAME}/g" /opt/lxcf/${LXCNAME}/etc/lxcf/container_name

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

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

  # create authorized_keys
  echo "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

  echo "created files " ${LXCNAME}

  # define new container
  /usr/lib64/lxcf/lxcf-define ${LXCNAME}

  # start new container
  /usr/lib64/lxcf/lxcf-start ${LXCNAME}

  # create known_hosts entry
  sed -i "/^${LXCNAME}[ |,]/d"  /root/.ssh/known_hosts
  ssh-keyscan localhost |& egrep "ssh-rsa" >> /root/.ssh/known_hosts
  LXCIPADR=`awk '{if ($2 == "'${LXCNAME}'") printf "%s",$1}' /etc/hosts`
  sed -i "s/localhost/${LXCNAME},${LXCIPADR}/" /root/.ssh/known_hosts

}

# Judges while executing the job. 
# UUID of the first job is passed from QUEUE when called from the job. 
UUID=""
PPPID=`ps -o pid,ppid | awk '{if ($1 == '${PPID}') print $2}'`
PPPPID=`ps -o pid,ppid | awk '{if ($1 == '${PPPID}') print $2}'`
QLINE=`egrep "^$PPPPID" /var/lib/lxcf/exjob`
if [ $? -eq 0 ]; then
	UUID=`echo ${QLINE} | awk '{print $2}'`
fi
PPID_CMD=`ps --no-headers -o cmd ${PPID} | awk '{print $1}'`
if [ x"${PPID_CMD}" = x"clone-n" ]; then
	UUID=""
fi

# clone containers of args
for name in $*
do
	lxcf_clone1 $name
done

exit 0
