#!/bin/bash

set -eux
set -o pipefail

export image_build=${1:-"default"}

# Attempt to be smart about detecting the path to the instack-undercloud
# elements
INSTACKUNDERCLOUDELEMENTS=/usr/share/instack-undercloud
if [ ! -d $INSTACKUNDERCLOUDELEMENTS ]; then
    INSTACKUNDERCLOUDELEMENTS=$(dirname $0)/../elements
fi

TRIPLEOPUPPETELEMENTS=/usr/share/tripleo-puppet-elements
if [ ! -d $TRIPLEOPUPPETELEMENTS ]; then
    # Assume it's checked out in the current directory
    TRIPLEOPUPPETELEMENTS=$PWD/tripleo-puppet-elements/elements
fi

export ELEMENTS_PATH=${ELEMENTS_PATH:-"\
$TRIPLEOPUPPETELEMENTS:\
$INSTACKUNDERCLOUDELEMENTS:\
/usr/share/tripleo-image-elements:\
/usr/share/diskimage-builder/elements:\
/usr/share/openstack-heat-templates/software-config/elements"}

# Override TMP_DIR for image build.
# It defaults /tmp. But, /tmp is usually tmpfs mounted on Fedora, and dib will
# use a tmpfs on it's own if there is enough free RAM.
export TMP_DIR=${TMP_DIR:-/var/tmp}

# We need to define this here, see:
# https://review.openstack.org/179502
export DIB_DEFAULT_INSTALLTYPE=${DIB_DEFAULT_INSTALLTYPE:-package}

export NODE_ARCH=${NODE_ARCH:-amd64}

export USE_DELOREAN_TRUNK=${USE_DELOREAN_TRUNK:-0}
export DELOREAN_TRUNK_REPO=${DELOREAN_TRUNK_REPO:-"http://trunk.rdoproject.org/kilo/centos7/latest-RDO-kilo-CI/"}
export DELOREAN_REPO_FILE=${DELOREAN_REPO_FILE:-"delorean-kilo.repo"}

export NODE_DIST=${NODE_DIST:-""}

# Attempt to detect $NODE_DIST, exit 1 if we can't
if [ -z "$NODE_DIST" ]; then
    if $(grep -Eqs 'Red Hat Enterprise Linux' /etc/redhat-release); then
        export NODE_DIST=${NODE_DIST:-rhel7}
    elif $(grep -Eqs 'CentOS' /etc/redhat-release); then
        export NODE_DIST=${NODE_DIST:-centos7}
    elif $(grep -Eqs 'Fedora' /etc/redhat-release); then
        export NODE_DIST=${NODE_DIST:-fedora}
    else
        echo "Could not detect distribution from /etc/redhat-release!"
        exit 1
    fi
fi

# Set specific variables based on $NODE_DIST
if [ "$NODE_DIST" = "rhel7" ]; then
    export REG_METHOD=${REG_METHOD:-disable}

    # EPEL/rdo get enabled when RHOS=0
    export RHOS=${RHOS:-"0"}
    # But we still actually need it to enable base RHEL repos.
    export RUN_RHOS_RELEASE=${RUN_RHOS_RELEASE:-"0"}
    if [ "${RUN_RHOS_RELEASE}" = "1" ]; then
        export RHOS_RELEASE=${RHOS_RELEASE:-6}
        export DIB_COMMON_ELEMENTS=rhos-release
    fi
    export DELOREAN_REPO_URL=$DELOREAN_TRUNK_REPO
elif [ "$NODE_DIST" = "centos7" ]; then
    export DELOREAN_REPO_URL=$DELOREAN_TRUNK_REPO
    # SELinux permissive for CentOS for now
    export DIB_COMMON_ELEMENTS="selinux-permissive centos-cloud-repo"
    # lshw has moved from EPEL to the CentOS cr repo.  However, at this time adding
    # the cr repo to the overcloud images results in openvswitch crashes, so we can
    # only add it to the discovery image.
    export DISCOVERY_IMAGE_ELEMENT="delorean-rdo-management ironic-discoverd-ramdisk-instack centos-cr"
fi

export DEPLOY_IMAGE_ELEMENT=${DEPLOY_IMAGE_ELEMENT:-deploy-ironic}
export DEPLOY_NAME=${DEPLOY_NAME:-deploy-ramdisk-ironic}
# Include delorean-rdo-management with the discovery ramdisk build so that we
# can install python-hardware from somewhere.
if [ "${RHOS:-0}" = "0" ]; then
    export DISCOVERY_IMAGE_ELEMENT=${DISCOVERY_IMAGE_ELEMENT:-"delorean-rdo-management ironic-discoverd-ramdisk-instack"}
else
    export DISCOVERY_IMAGE_ELEMENT=${DISCOVERY_IMAGE_ELEMENT:-"ironic-discoverd-ramdisk-instack"}
fi
export DISCOVERY_NAME=${DISCOVERY_NAME:-discovery-ramdisk}

export DIB_COMMON_ELEMENTS=${DIB_COMMON_ELEMENTS:-""}
export DIB_COMMON_ELEMENTS="$DIB_COMMON_ELEMENTS \
element-manifest \
network-gateway \
"

if [[ "rhel7 centos7" =~ "$NODE_DIST" ]]; then
    # Default filesystem type is XFS for RHEL 7
    export FS_TYPE=${FS_TYPE:-xfs}
fi

if [ "$NODE_DIST" = "rhel7" ]; then
    export RHOS_RELEASE=${RHOS_RELEASE:-"0"}
    if [ "$RHOS" = "0" ]; then
        export RDO_RELEASE=kilo
        export DIB_COMMON_ELEMENTS="$DIB_COMMON_ELEMENTS epel rdo-release"
    elif [ ! "$RHOS_RELEASE" = "0" ]; then
        export DIB_COMMON_ELEMENTS="$DIB_COMMON_ELEMENTS rhos-release"
    fi
elif [ "$NODE_DIST" = "centos7" ]; then
    export RDO_RELEASE=kilo
    export DIB_COMMON_ELEMENTS="$DIB_COMMON_ELEMENTS epel rdo-release"
fi

export PACKAGES=${PACKAGES:-"1"}
if [ "$PACKAGES" = "1" ]; then
    export DIB_COMMON_ELEMENTS="$DIB_COMMON_ELEMENTS undercloud-package-install pip-and-virtualenv-override"
fi

# Puppet overcloud-specific configuration
export PUPPET_COMMON_ELEMENTS="\
sysctl \
hosts \
baremetal \
dhcp-all-interfaces \
os-collect-config \
heat-config-puppet \
heat-config-script \
puppet-modules \
hiera \
os-net-config \
stable-interface-names \
grub2-deprecated \
-p python-psutil,python-debtcollector \
"

if [ "$USE_DELOREAN_TRUNK" = "1" ]; then
    export PUPPET_COMMON_ELEMENTS="$PUPPET_COMMON_ELEMENTS delorean-repo"
fi

export OVERCLOUD_FULL_DIB_EXTRA_ARGS=${OVERCLOUD_FULL_DIB_EXTRA_ARGS:-"\
$PUPPET_COMMON_ELEMENTS \
overcloud-full \
overcloud-controller \
overcloud-compute \
overcloud-ceph-storage \
"}

# There are new deps on python-psutil and python-debtcollector but the Nova and Cinder
# packages are not updated yet to actually require them.
export OVERCLOUD_CONTROL_DIB_EXTRA_ARGS=${OVERCLOUD_CONTROL_DIB_EXTRA_ARGS:-"\
$PUPPET_COMMON_ELEMENTS
overcloud-controller \
"}

export OVERCLOUD_COMPUTE_DIB_EXTRA_ARGS=${OVERCLOUD_COMPUTE_DIB_EXTRA_ARGS:-"\
$PUPPET_COMMON_ELEMENTS
overcloud-compute
"}


export OVERCLOUD_CEPHSTORAGE_DIB_EXTRA_ARGS=${OVERCLOUD_CEPHSTORAGE_DIB_EXTRA_ARGS:-"\
$PUPPET_COMMON_ELEMENTS
overcloud-ceph-storage \
"}

export OVERCLOUD_CINDER_DIB_EXTRA_ARGS=${OVERCLOUD_CINDER_DIB_EXTRA_ARGS:-"\
baremetal \
base \
cinder-lio \
common-venv \
dhcp-all-interfaces \
hosts \
ntp \
os-collect-config \
pip-cache \
pypi-openstack \
snmpd \
stable-interface-names \
use-ephemeral \
sysctl \
"}

export OVERCLOUD_SWIFT_DIB_EXTRA_ARGS=${OVERCLOUD_SWIFT_DIB_EXTRA_ARGS:-"\
pip-cache \
pypi-openstack \
swift-storage \
os-collect-config \
baremetal \
base \
common-venv \
dhcp-all-interfaces \
hosts \
ntp \
snmpd \
stable-interface-names \
use-ephemeral \
os-refresh-config-reboot \
sysctl \
"}

function deploy-ramdisk {
if [ ! -f $DEPLOY_NAME.initramfs -o \
     ! -f $DEPLOY_NAME.kernel ]; then
    ramdisk-image-create \
        -a $NODE_ARCH \
        -o $DEPLOY_NAME \
        --ramdisk-element dracut-ramdisk \
        $NODE_DIST $DEPLOY_IMAGE_ELEMENT \
        $DIB_COMMON_ELEMENTS \
        2>&1 | tee dib-deploy.log
fi
}

function discovery-ramdisk {
    if [ ! -f $DISCOVERY_NAME.initramfs -o \
         ! -f $DISCOVERY_NAME.kernel ]; then
        ramdisk-image-create \
            -a $NODE_ARCH \
            -o $DISCOVERY_NAME \
            --ramdisk-element dracut-ramdisk \
            $NODE_DIST $DISCOVERY_IMAGE_ELEMENT \
            $DIB_COMMON_ELEMENTS \
            2>&1 | tee dib-discovery.log
    fi
}

function overcloud-control {
    if [ ! -f overcloud-control.qcow2 ]; then
        disk-image-create \
            -a $NODE_ARCH \
            -o overcloud-control \
            $NODE_DIST \
            $OVERCLOUD_CONTROL_DIB_EXTRA_ARGS \
            $DIB_COMMON_ELEMENTS \
            2>&1 | tee dib-overcloud-control.log
    fi
}

function overcloud-compute {
    if [ ! -f overcloud-compute.qcow2 ]; then
        disk-image-create \
            -a $NODE_ARCH \
            -o overcloud-compute \
            $NODE_DIST  \
            $OVERCLOUD_COMPUTE_DIB_EXTRA_ARGS \
            $DIB_COMMON_ELEMENTS \
            2>&1 | tee dib-overcloud-compute.log
    fi
}

function overcloud-ceph-storage {
    if [ ! -f overcloud-ceph-storage.qcow2 ]; then
        disk-image-create \
            -a $NODE_ARCH \
            -o overcloud-ceph-storage \
            $NODE_DIST  \
            $OVERCLOUD_CEPHSTORAGE_DIB_EXTRA_ARGS \
            $DIB_COMMON_ELEMENTS \
            2>&1 | tee dib-overcloud-ceph-storage.log
    fi
}

function overcloud-cinder-volume {
    if [ ! -f overcloud-cinder-volume.qcow2 ]; then
        disk-image-create \
            -a $NODE_ARCH \
            -o overcloud-cinder-volume \
            $NODE_DIST \
            $OVERCLOUD_CINDER_DIB_EXTRA_ARGS \
            $DIB_COMMON_ELEMENTS \
            2>&1 | tee dib-overcloud-cinder-volume.log
    fi
}

function overcloud-swift-storage {
    if [ ! -f overcloud-swift-storage.qcow2 ]; then
        disk-image-create \
            -a $NODE_ARCH \
            -o overcloud-swift-storage \
            $NODE_DIST \
            $OVERCLOUD_SWIFT_DIB_EXTRA_ARGS \
            $DIB_COMMON_ELEMENTS \
            2>&1 | tee dib-overcloud-swift-storage.log
    fi
}

function fedora-user {
    if [ ! -f fedora-user.qcow2 ]; then
        if [ -f ~/.cache/image-create/fedora-21.x86_64.qcow2 ]; then
            # Just copy the already downloaded Fedora cloud image as fedora-user.qcow2
            cp ~/.cache/image-create/fedora-21.x86_64.qcow2 fedora-user.qcow2
        else
            # Download the image
            curl -o fedora-user.qcow2 -L http://cloud.fedoraproject.org/fedora-21.x86_64.qcow2
        fi
        # The perms always seem to be wrong when copying out of the cache, so
        # fix them
        chmod 644 fedora-user.qcow2
    fi
}

function overcloud-full {
    if [ ! -f overcloud-full.qcow2 ]; then
        disk-image-create \
            -a $NODE_ARCH \
            -o overcloud-full \
            $NODE_DIST \
            $OVERCLOUD_FULL_DIB_EXTRA_ARGS \
            $DIB_COMMON_ELEMENTS \
            $PUPPET_COMMON_ELEMENTS \
            2>&1 | tee dib-overcloud-full.log
    fi
}

function os-disk-config {
    # Super basic image including os-disk-config for demonstrating its functionality
    if [ ! -f os-disk-config.qcow2 ]; then
        unset DIB_COMMON_ELEMENTS
        disk-image-create \
            -a $NODE_ARCH \
            -o os-disk-config \
            $NODE_DIST \
            os-disk-config baremetal \
            2>&1 | tee dib-os-disk-config.log
    fi
}

if [ "$image_build" = "default" ]; then
    fedora-user
    deploy-ramdisk
    discovery-ramdisk
    overcloud-full
    echo "Successfully built all necessary images."
else
    eval "$image_build"
    echo "Successfully built $image_build image."
fi
