# lib/nova_plugins/docker
# Configure the Docker hypervisor

# Enable with:
# VIRT_DRIVER=docker

# Dependencies:
# ``functions`` file
# ``nova`` and ``glance`` configurations

# install_nova_hypervisor - install any external requirements
# configure_nova_hypervisor - make configuration changes, including those to other services
# start_nova_hypervisor - start any external services
# stop_nova_hypervisor - stop any external services
# cleanup_nova_hypervisor - remove transient data and cache

# Save trace setting
MY_XTRACE=$(set +o | grep xtrace)
set +o xtrace


# Defaults
# --------

# Set up default directories
DOCKER_DIR=$DEST/docker
DOCKER_REPO=${DOCKER_REPO:-https://github.com/dotcloud/openstack-docker.git}
DOCKER_BRANCH=${DOCKER_BRANCH:-master}

DOCKER_UNIX_SOCKET=/var/run/docker.sock
DOCKER_PID_FILE=/var/run/docker.pid
DOCKER_REGISTRY_PORT=${DOCKER_REGISTRY_PORT:-5042}

DOCKER_IMAGE=${DOCKER_IMAGE:-http://get.docker.io/images/openstack/docker-ut.tar.gz}
DOCKER_IMAGE_NAME=docker-busybox
DOCKER_REGISTRY_IMAGE=${DOCKER_REGISTRY_IMAGE:-http://get.docker.io/images/openstack/docker-registry.tar.gz}
DOCKER_REGISTRY_IMAGE_NAME=docker-registry
DOCKER_REPOSITORY_NAME=${SERVICE_HOST}:${DOCKER_REGISTRY_PORT}/${DOCKER_IMAGE_NAME}

DOCKER_PACKAGE_VERSION=${DOCKER_PACKAGE_VERSION:-0.6.1}
DOCKER_APT_REPO=${DOCKER_APT_REPO:-https://get.docker.io/ubuntu}


# Entry Points
# ------------

# clean_nova_hypervisor - Clean up an installation
function cleanup_nova_hypervisor() {
    stop_service docker

    # Clean out work area
    sudo rm -rf /var/lib/docker
}

# configure_nova_hypervisor - Set config files, create data dirs, etc
function configure_nova_hypervisor() {
    git_clone $DOCKER_REPO $DOCKER_DIR $DOCKER_BRANCH

    ln -snf ${DOCKER_DIR}/nova-driver $NOVA_DIR/nova/virt/docker

    iniset $NOVA_CONF DEFAULT compute_driver docker.DockerDriver
    iniset $GLANCE_API_CONF DEFAULT container_formats ami,ari,aki,bare,ovf,docker

    sudo cp -p ${DOCKER_DIR}/nova-driver/docker.filters $NOVA_CONF_DIR/rootwrap.d
}

# install_nova_hypervisor() - Install external components
function install_nova_hypervisor() {
    # So far this is Ubuntu only
    if ! is_ubuntu; then
        die $LINENO "Docker is only supported on Ubuntu at this time"
    fi

    # Make sure Docker is installed
    if ! is_package_installed lxc-docker; then
        die $LINENO "Docker is not installed.  Please run tools/docker/install_docker.sh"
    fi

    local docker_pid
    read docker_pid <$DOCKER_PID_FILE
    if [[ -z $docker_pid ]] || ! ps -p $docker_pid | grep [d]ocker; then
        die $LINENO "Docker not running"
    fi
}

# start_nova_hypervisor - Start any required external services
function start_nova_hypervisor() {
    local docker_pid
    read docker_pid <$DOCKER_PID_FILE
    if [[ -z $docker_pid ]] || ! ps -p $docker_pid | grep [d]ocker; then
        die $LINENO "Docker not running, start the daemon"
    fi

    # Start the Docker registry container
    docker run -d -p ${DOCKER_REGISTRY_PORT}:5000 \
        -e SETTINGS_FLAVOR=openstack -e OS_USERNAME=${OS_USERNAME} \
        -e OS_PASSWORD=${OS_PASSWORD} -e OS_TENANT_NAME=${OS_TENANT_NAME} \
        -e OS_GLANCE_URL="${SERVICE_PROTOCOL}://${GLANCE_HOSTPORT}" \
        -e OS_AUTH_URL=${OS_AUTH_URL} \
        $DOCKER_REGISTRY_IMAGE_NAME ./docker-registry/run.sh

    echo "Waiting for docker registry to start..."
    DOCKER_REGISTRY=${SERVICE_HOST}:${DOCKER_REGISTRY_PORT}
    if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl -s $DOCKER_REGISTRY; do sleep 1; done"; then
        die $LINENO "docker-registry did not start"
    fi

    # Tag image if not already tagged
    if ! docker images | grep $DOCKER_REPOSITORY_NAME; then
        docker tag $DOCKER_IMAGE_NAME $DOCKER_REPOSITORY_NAME
    fi

    # Make sure we copied the image in Glance
    DOCKER_IMAGE=$(glance image-list | egrep " $DOCKER_IMAGE_NAME ")
    if ! is_set DOCKER_IMAGE ; then
        docker push $DOCKER_REPOSITORY_NAME
    fi
}

# stop_nova_hypervisor - Stop any external services
function stop_nova_hypervisor() {
    # Stop the docker registry container
    docker kill $(docker ps | grep docker-registry | cut -d' ' -f1)
}


# Restore xtrace
$MY_XTRACE

# Local variables:
# mode: shell-script
# End:
