#!/bin/sh -e
# Script to create ploop images for Virtuozzo Infrastructure Platform
# The following templates are possible:
#     vzlinux-7, centos-7, ubuntu-16.04, debian-8.0

set -e

mkimg="$(basename "$0")"

usage() {
    echo >&2 "usage: $mkimg --template=vzlinux-7|centos-7|ubuntu-16.04|debian-8.0"
    echo >&2 "usage: $mkimg --template=centos-7 --extra-package='vim-minimal iproute'"
    echo >&2 "usage: $mkimg --template=centos-7 --flavor=full|micro|pico"
    echo >&2 "       flavors sizes:"
    echo >&2 "             full  ~950Mb"
    echo >&2 "             micro ~535Mb"
    echo >&2 "             pico  ~305Mb"
    exit 1
}

optTemp=$(getopt --options '+t,h,+f,+x,+n' --longoptions 'template:,help,flavor:,extra-package:,network-adapters:' --name container-image -- "$@")
eval set -- "$optTemp"
unset optTemp

flavor="full"
network_adapters="2"

while true; do
    case "$1" in
        -t|--template) template="$2" shift 2 ;;
        -f|--flavor) flavor="$2" ; shift 2 ;;
        -h|--help) usage ;;
        -x|--extra-package) extra_package="$2" ; shift 2 ;;
        -n|--network-adapters) network-adapters="$2" ; shift 2 ;;
        --) shift ; break ;;
    esac
done

if [[ -z $template ]]; then
    usage
fi

if [[ "$flavor" == "micro" ]]; then
    echo "image flavor is $flavor"
elif [[ "$flavor" == "full" ]]; then
    echo "leaving image as is"
elif [[ "$flavor" == "pico" ]]; then
    echo "image flavor is $flavor"
else
    usage
fi

trap errorCatch ERR SIGHUP SIGINT SIGTERM

function errorCatch() {
    echo "Error catched. Exiting"
    echo "probably you need to remove created image"
    prlctl list -a
    prlctl stop $template-$random_digit
    prlctl destroy $template-$random_digit
    exit 1
}

function create_container() {
export template="$template"
export flavor="$flavor"
export extra_package="$extra_package"
random_digit=$(( $RANDOM % 100 + 40 ));
prlctl create $template-$random_digit --vmtype ct --ostemplate $template
prlctl start $template-$random_digit

export uuid=$(vzlist $template-$random_digit | awk ' NR>1 { print $1 }')

}

function common_wipe () {
    echo "wipe %_mandir and %_docdir"
    prlctl exec $template-$random_digit rm -rf /usr/share/{man,doc,info,gnome/help} /usr/share/cracklib /usr/share/i18n /var/cache/yum /var/cache/apt/archives
}

function stop_and_mount () {
    prlctl stop $template-$random_digit
    prlctl mount $template-$random_digit
}
function common_tune () {
    rm -f /vz/root/$uuid/etc/resolv.conf
    # remove unnecessary cloud-init modules
    sed -i '/- growpart/d' /vz/root/$uuid/etc/cloud/cloud.cfg
    sed -i '/- resizefs/d' /vz/root/$uuid/etc/cloud/cloud.cfg
}


function centos_networking () {
    echo "setup $network_adapters network adapters"
    for ((i=0;i<$network_adapters;i++)) {
    cat > /vz/root/$uuid/etc/sysconfig/network-scripts/ifcfg-eth$i << _EOF
DEVICE=eth$i
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=dhcp
_EOF
}
    echo "perfome minor cleanup"
    rm -f /vz/root/$uuid/etc/sysconfig/network-scripts/ifcfg-venet0*
}


function prepare_centos_like () {
# run create container function here
create_container
# packages for removeal to reduce image size
yum_command="yum remove -y"
yum_packages="samba-client lm_sensors-libs wget m4 centos-logos avahi-libs screen mariadb-libs samba-common fipscheck-lib fipscheck quota tmpwatch stunnel json-c ftp perl-parent man-pages mlocate httpd-tools rpcbind hunspell telnet ebtables talk-server lsof traceroute rsync procmail man-db logrotate python-decorator slang python-slip tcsh net-snmp-libs make mailcap libtevent finger apr gobject-introspection firewalld-filesystem ncompress quota-nls hesiod libtdb talk e2fsprogs usermode cronie ed elfutils vim-common vim-minimal unzip bind-license"

if [[ "$flavor" == "micro" ]]; then
    prlctl exec $template-$random_digit $yum_command $yum_packages
fi
if [[ "$flavor" == "pico" ]]; then
    prlctl exec $template-$random_digit $yum_command $yum_packages
    common_wipe
fi

if [[ "$template" =~ vzlinux-7 ]]; then
    prlctl exec $template-$random_digit useradd virtuozzo
fi
vzpkg install $template-$random_digit -p $extra_package openssh-server dhclient cloud-init sudo || if [[ $? != 0 ]]; then errorCatch; fi

stop_and_mount

centos_networking

common_tune

}

function debian7_repo_contrib () {
repofile="/vz/template/debian/7.0/x86_64/config/os/default/repositories"
if [ -s "$repofile" ]; then
if grep --quiet backports $repofile; then
  echo "contrib repo already added"
else
  echo "\$DEB_SERVER/debian wheezy-backports main contrib" >> $repofile
fi
fi

}

function debian_networking () {
    echo "setup $network_adapters network adapters"
    rm -f /vz/root/$uuid/etc/network/interfaces

    for ((i=0;i<$network_adapters;i++)) {

    cat >> /vz/root/$uuid/etc/network/interfaces << _EOF
auto eth$i
iface eth$i inet dhcp

_EOF
}

}


function prepare_debian_like () {
# run create container function here
create_container
# packages for removeal to reduce image size
apt_command="apt-get autoremove -y"
apt_packages="tcpdump samba-common-bin samba-common samba screen wget whois xinetd postfix plymouth m4 make telnet snmp unixodbc tdb-tools memtester mlocate initramfs-tools apache2 apache2-doc apache2-utils bind9 bind9-host bind9utils fontconfig fontconfig-config odbcinst odbcinst1debian2 openssh-blacklist openssh-client openssh-server vim-runtime vim-common vim"

if [[ "$template" =~ debian-7.0 ]]; then
    debian7_repo_contrib
fi

if [[ "$flavor" == "micro" && "$template" != "debian-8.0-x86_64-minimal" ]]; then
    prlctl exec $template-$random_digit $apt_command $apt_packages || if [[ $? != 0 ]]; then errorCatch; fi
fi
if [[ "$flavor" == "pico" && "$template" != "debian-8.0-x86_64-minimal" ]]; then
    prlctl exec $template-$random_digit $apt_command $apt_packages || if [[ $? != 0 ]]; then errorCatch; fi
    common_wipe
fi
    vzpkg install $template-$random_digit -p $extra_package cloud-init openssh-server || if [[ $? != 0 ]]; then errorCatch; fi
if [[ "$flavor" == "pico" ]]; then
    common_wipe
fi

stop_and_mount

debian_networking

common_tune

}

function fill_content () {
    DIST_DIR=/tmp/ploop-$template-$random_digit
    echo "create target dir"
    mkdir $DIST_DIR
    ploop init -s 950M $DIST_DIR/$template.hds > /dev/null 2>&1
    mkdir $DIST_DIR/dst
    ploop mount -m $DIST_DIR/dst $DIST_DIR/DiskDescriptor.xml
    cp -Pr --preserve=all /vz/root/$uuid/* $DIST_DIR/dst/
    ploop umount -m $DIST_DIR/dst/
    prlctl umount $template-$random_digit
    prlctl destroy $template-$random_digit
    echo "=================="
    echo "Container is ready"
    echo "=================="
    echo "Image path: $DIST_DIR/$template.hds"
    image_size=$(ls -lh $DIST_DIR/$template.hds | awk '{print $5}')
    echo "Template: $template"
if [[ -z "$flavor" ]]; then
    echo "Flavor: $flavor"
fi
    echo "Size: $image_size"
    echo "cleanup /tmp"
    rm -rf /tmp/$DIST_DIR
}

if [[ "$template" =~ centos-* ]] || [[ "$template" =~ vzlinux-7 ]]; then
prepare_centos_like
fi
if [[ "$template" =~ ubuntu-* ]] || [[ "$template" =~ debian-* ]]; then
prepare_debian_like
fi

fill_content
