#!/bin/bash

# LXCF - LXC Facility
# Copyright (C) 2013-2014 FUJITSU LIMITED

# 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 distro
DISTRO=`/usr/lib64/lxcf/lxcf-distro`

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

umask 022

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

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

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

# check default separate model
/usr/lib64/lxcf/lxcf-config
if [ -f /etc/lxcf/separate ] ; then
  FLG_S=1 ; VAL_SEPARATE="-s"
else
  FLG_S=0 ; VAL_SEPARATE="-j"
fi

# check options
FLG_H=0 ; VAL_HOME=""
FLG_O=0 ; VAL_OPT=""
FLG_C=0 ; JSONFILE=""
FLG_P=0 ; FILEPATH=""

while getopts hosjc:p: OPT ; do
  case $OPT in
  h) FLG_H=1 ; VAL_HOME="-h" ;;
  o) FLG_O=1 ; VAL_OPT="-o" ;;
  s) FLG_S=1 ; VAL_SEPARATE="-s" ;;
  j) FLG_S=0 ; VAL_SEPARATE="-j" ;;
  c) FLG_C=1 ; JSONFILE=$OPTARG ;;
  p) FLG_P=1 ; FILEPATH=$OPTARG ;;
  esac
done
shift $((OPTIND - 1))

# check args
if [ $# -eq 0 ] ; then
  cat <<- EOF
	usage lxcf ${0##*/} [-h] [-o] [-s] [-j] [-c configfile] LXCNAME
	EOF
  exit 1
fi

# check jsonfile
if [ $FLG_C -eq 1 ] ; then
  if ! /usr/lib64/lxcf/lxcf-check-json $JSONFILE ; then
    echo "error: illegal format json file: $JSONFILE"
    exit 1
  fi
fi

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

# generate one container
lxcf_sysgen1() {
  LXCNAME=$1

  NAMELEN=${#LXCNAME}
  if [ $NAMELEN -gt 16 ]; then
    echo "error: too long name:" $LXCNAME
    exit 1
  fi

  if [ -n "`/usr/bin/virsh list --all | tail -n+3 | awk '{ print $2 }' \
      | grep ^$LXCNAME$`" ] ; then
    echo "error: The same VM name already exists: $LXCNAME"
    return
  elif [ -n "`/usr/bin/virsh -c lxc:/// list --all | tail -n+3 | awk '{ print $2 }' \
      | grep ^$LXCNAME$`" ] ; then
    echo "error: The same LXC name already exists: $LXCNAME"
    return
  elif ! /usr/lib64/lxcf/lxcf-parmchk-cname $LXCNAME ; then
    cat <<- EOF
	error: $LXCNAME is not a container name.
	       The container name must be alphanumeric character, "-" and "_".
	EOF
    exit 1
  fi

  rootfs=/opt/lxcf/$LXCNAME

  # check LXCNAME
  if [ -d $rootfs ] ; then
    echo "error: There is already $LXCNAME"
    exit 1
  fi

  echo "Generating $LXCNAME..."
  trap '/usr/lib64/lxcf/lxcf-erase $LXCNAME ; exit 1' 2

  # set symbolic link for -p option
  if [ $FLG_P -eq 1 ] ; then
    mkdir -p $FILEPATH/$LXCNAME
    ln -s $FILEPATH/$LXCNAME $rootfs
  fi

  # main operation
  /usr/lib64/lxcf/lxcf-createfile $VAL_HOME $VAL_OPT $VAL_SEPARATE $LXCNAME
  /usr/lib64/lxcf/lxcf-clearlog $LXCNAME

  # UUID of queue is passed, if sysgen is called from job
  [ -f /etc/lxcf/rsc/$LXCNAME/uuid ] && UUID=""

  if [ x$DISTRO == x"u" ]; then
    /usr/lib64/lxcf/lxcf-setup-u $VAL_SEPARATE $LXCNAME
  elif [ x$DISTRO == x"f" ]; then
    /usr/lib64/lxcf/lxcf-setup-f $VAL_SEPARATE $LXCNAME
  fi

  [ -f /etc/lxcf/rsc/$LXCNAME/uuid -a -n "$UUID" ] \
      && echo -n "$UUID" > /etc/lxcf/rsc/$LXCNAME/uuid
  UUID=""

  cp -p /opt/lxcf/$LXCNAME/etc/lxcf/container_name /etc/lxcf/rsc/$LXCNAME/container_name

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

  # disable lxcf.service
  #if [ -h $rootfs/etc/systemd/system/multi-user.target.wants/lxcf.service ] ; then
  #  rm $rootfs/etc/systemd/system/multi-user.target.wants/lxcf.service
  #fi

  # create an initial rsc file
  /usr/lib64/lxcf/lxcf-resource1 initrsc $LXCNAME > /etc/lxcf/rsc/$LXCNAME/resource.val

  /usr/lib64/lxcf/lxcf-start $LXCNAME

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

  # set resource
  if [ $FLG_C -eq 1 ] ; then
    echo "loading json file: $JSONFILE"
    /usr/lib64/lxcf/lxcf-load $LXCNAME $JSONFILE
  fi
  #/usr/lib64/lxcf/lxcf-resource show $LXCNAME
}

# erase yum chache
if [ -x /usr/bin/yum ] ; then
  yum clean packages > /dev/null 2>&1
  yum clean all > /dev/null 2>&1
fi

# erase apt cache
if [ -x /usr/bin/apt-get ] ; then
  apt-get autoclean >& /dev/null
  apt-get clean >& /dev/null
fi

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

# judge 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}"`
if QLINE=`grep "^$PPPPID" /var/lib/lxcf/exjob` ; then
  UUID=`echo -n $QLINE | awk '{print $2}'`
fi
[ "`ps -h -o comm $PPID`" == "sysgen-n" ] && UUID=""

# generate containers of args
for i in "$@" ; do lxcf_sysgen1 "$i" ; done

exit 0
