#!/bin/sh
#  lxc_native.c: LXC native configuration import
#
#  Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
#  This library is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2.1 of the License, or (at your option) any later version.
#
#  This library 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
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library.  If not, see
#  <http://www.gnu.org/licenses/>.
#

handler_cleanup()
{
    if test "$conf_dir"; then
        # Remove the temporary config
        rm -r "$conf_dir"
    fi
}
trap handler_cleanup INT EXIT

show_help()
{
    cat << EOF
$0 /path/to/lxc/config/file

Wrapper around virsh domxml-from-native to ease conversion of LXC
containers configuration to libvirt domain XML.
EOF
}

if test $# != 1; then
    show_help
    exit 1
fi

if test "$1" = "--help" || test "$1" = "-h"; then
    show_help
    exit $?
fi

conf=$1

conf_dir=$(mktemp --tmpdir -d virt-lxc-convert-XXX)
conf_new=$conf_dir/config

cp "$conf" "$conf_new"

# Do we have lxc.mount, and is it pointing to a readable file?
fstab=$(sed -n '/lxc.mount[[:space:]]*=/ s/[[:space:]]*=[[:space:]]*/=/p' \
        "$conf_new" | cut -f 2 -d '=')
if test -r "$fstab"; then
    sed 's/^lxc.mount[[:space:]]*=.*$//' "$conf_new" >"${conf_new}.tmp"
    mv "${conf_new}.tmp" "${conf_new}"
    sed 's/^\([^#]\)/lxc.mount.entry = \1/' "$fstab" >>"${conf_new}"
fi

memory=$(free -b | sed -n '/Mem:/s/ \+/ /gp' | cut -f 2 -d ' ')
default_tmpfs="size=$((memory/2))"

# Do we have tmpfs without size param?
lineno=0
while read line; do
    lineno=$(expr $lineno + 1)
    has_rel_size=false
    case $line in
        lxc.mount.entry[[:space:]]*=[[:space:]]*tmpfs[[:space:]]*)
            is_tmpfs=true
            ;;
        *)
            is_tmpfs=false
            ;;
    esac

    # We only care about tmpfs mount entries here
    if ! $is_tmpfs; then
        continue
    fi

    case $line in
        *size=[0-9][0-9]*%*)
            has_rel_size=true
            has_size=true
            ;;
        *size=*)
            has_size=true
            ;;
        *)
            has_size=false
            ;;
    esac

    # Add the default size here (50%) if no size is given
    if ! $has_size; then
        last_option_match="\([[:space:]]*[0-9][[:space:]]*[0-9][::space::]*$\)"
        sed "${lineno}s/$last_option_match/,$default_tmpfs\1/" \
            "$conf_new" >"${conf_new}.tmp"
        mv "${conf_new}.tmp" "${conf_new}"
    fi

    # Convert relative sizes
    if $has_rel_size; then
        percent=$(echo "$line" | sed 's/.*size=\([0-9][0-9]*\)%.*/\1/')
        size="$((memory*percent/100))"
        sed "${lineno}s/size=[0-9]*%/size=${size}/" \
            "$conf_new" >"${conf_new}.tmp"
        mv "${conf_new}.tmp" "${conf_new}"
    fi
done < "$conf_new"

# Do we have any memory limit set?
mem_limit=$(grep 'lxc.cgroup.memory.limit_in_bytes[[:space:]]*=' $conf_new)
if test -z "$mem_limit"; then
    echo "lxc.cgroup.memory.limit_in_bytes = $memory" >> "$conf_new"
fi

virsh -c lxc:///system domxml-from-native lxc-tools $conf_new
exit $?
