
#################################################################
#
# Docker specific functions.
#
# Author: TODO
#
################################################################
#
# Copyright (c) 2017 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# 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 (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################

recipe_setup_docker() {
    TOPDIR="/usr/src/packages"
    mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES"
    mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES/packages"

    echo "Copying packages"
    for package in $(find repos -name \*.rpm); do
        cp $package "$BUILD_ROOT$TOPDIR/SOURCES/packages/"
    done

    # Exclude the "repos" directory which was handled above
    find . -maxdepth 1 ! -name "repos" ! -name '.' -exec cp -rp -t $BUILD_ROOT$TOPDIR/SOURCES/ {} \+
}

recipe_prepare_docker() {
    :
}

# Variables:
# $BUILD_ROOT is the chroot
# $TOPDIR/SOURCES includes the docker sources
# $TOPDIR/$DOCKERIMAGE_ROOT where docker will be called
# $RECIPEFILE the name of the Dockerfile

recipe_build_docker() {
    touch $BUILD_ROOT/etc/resolv.conf
    chmod 755 $BUILD_ROOT/$TOPDIR/SOURCES/obs_pkg_mgr

    echo "Starting container daemon"
    chroot $BUILD_ROOT /usr/sbin/containerd --listen unix:///run/containerd/containerd.sock &
    echo "Starting docker daemon"
    chroot $BUILD_ROOT /usr/bin/dockerd --containerd /run/containerd/containerd.sock --add-runtime oci=/usr/bin/docker-runc &
    echo "Waiting for docker daemon to start"
    for i in 1 2 3 4 5 6 7 8 9 10 ; do
        chroot $BUILD_ROOT docker version >/dev/null 2>&1 && break
        sleep 1
    done
    if ! chroot $BUILD_ROOT docker version >/dev/null 2>&1 ; then
        echo  "Docker is dead"
        cleanup_and_exit 1
    fi

    echo "Loading base image"
    base_image_path=$(find containers -regextype egrep -regex ".*\.(tgz|tar|xz).{0,4}$" -print -quit)

    # Inspect the content of the image to decide if this is a layered image
    # or a filesystem one. We need to know if we will "docker load" it or
    # "docker import" it.
    if tar -tf $base_image_path | grep "^manifest.json" -q; then
        echo "Layered image found"
        chroot $BUILD_ROOT docker load --input $TOPDIR/SOURCES/$base_image_path
    else
        echo "Filesystem image found"
        desired_tag=$(grep "^\s*FROM" Dockerfile | cut -d" " -f2)
        chroot $BUILD_ROOT docker import $TOPDIR/SOURCES/$base_image_path $desired_tag
    fi

    # Start the local zypper repository
    # TODO [TBD] Should we inject the OBS_REPOSITORY_URL in the Dockerfile as described in
    # the following link or is this a user's responsibility?
    #  https://github.com/SUSE/cloudfoundry/blob/NativeDockerInOBS_research_results/NativeDockerInOBS.md
    # TODO [TBD] What about SLES? Are dependencies fetched automatically from osc/OBS?
    #  What about registration?

    # This is where we copied the downloaded dependencies in the setup method above.
    REPOPATH=$TOPDIR/SOURCES/packages
    # Prepare the zypper repository
    # TODO: Handle other distribution repositories as well (deb, arch etc)
    chroot $BUILD_ROOT createrepo $REPOPATH > /dev/null
    # TODO Add Python as a default building dependency.
    chroot $BUILD_ROOT bash -c "cd $REPOPATH && python -m SimpleHTTPServer 8080 &"

    # Build the repository url
    REPO_URL=http://127.0.0.1:8080/

    # Create the needed file to publish the generated image
    if [ -f "TAG" ] && [ $(cat TAG | grep ":") ]; then
        IMAGE_NAME=$(cat TAG | cut -d":" -f1)
        TAG=$(cat TAG | cut -d":" -f2)
    fi

    if [ -z "$IMAGE_NAME" ] || [ -z "$TAG" ]; then
        echo "TAG file missing of contents invalid (use image_name:tag format)"
        cleanup_build_processes
        BUILD_SUCCEEDED=false
        return
    fi

    # Use tag to generate the filename for the image
    FILENAME="$IMAGE_NAME:$TAG"
    FILENAME="${FILENAME//[\/:]/-}"

    echo "Building image"
    if ! chroot $BUILD_ROOT docker build -t "$IMAGE_NAME:$TAG" --build-arg obs_repository_url=$REPO_URL $TOPDIR/SOURCES/ ; then
        echo "Docker build command failed"
        cleanup_build_processes
        BUILD_SUCCEEDED=false
        return
    fi

    # Save the resulting image to a tarball.
    mkdir -p $BUILD_ROOT$TOPDIR/DOCKER
    if ! chroot $BUILD_ROOT docker save --output $TOPDIR/DOCKER/$FILENAME.tar "$IMAGE_NAME:$TAG" ; then
        echo "Docker save command failed"
        cleanup_build_processes
        BUILD_SUCCEEDED=false
        return
    fi
    

    cat > $BUILD_ROOT$TOPDIR/DOCKER/$FILENAME.containerinfo <<containerinfo
{
  "name": "$FILENAME",
  "tags": [ "$IMAGE_NAME:$TAG" ],
  "file": "$FILENAME.tar"
}
containerinfo

    cleanup_build_processes

    BUILD_SUCCEEDED=true
}

cleanup_build_processes() {
    echo "Stopping local repository server"
    kill $(pgrep -f "python -m SimpleHTTPServer 8080")
    echo "Stopping the docker daemon"
    kill $(pidof dockerd)
    kill $(pidof containerd)
}

recipe_resultdirs_docker() {
    echo DOCKER
}

# Local Variables:
# mode: Shell-script
# End:
